package edu.xust.MetadataGenerator;

import java.awt.Dimension;
import java.awt.EventQueue;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JToolBar;

import java.awt.BorderLayout;

import javax.swing.JButton;
import javax.swing.JSplitPane;
import javax.swing.JTree;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JPopupMenu;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.JScrollPane;

//import net.sf.jasperreports.engine.JRDataSource;
//import net.sf.jasperreports.engine.data.JRBeanArrayDataSource;

import org.apache.log4j.Logger;
import org.jxls.common.Context;
import org.jxls.reader.ReaderBuilder;
import org.jxls.reader.ReaderConfig;
import org.jxls.reader.XLSReader;
import org.jxls.util.JxlsHelper;
import org.jxls.util.TransformerFactory;
import org.apache.log4j.LogManager;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import blackstone.FileTransfer;
import edu.xust.MetadataGenerator.domain.API;
import edu.xust.MetadataGenerator.domain.APIParam;
import edu.xust.MetadataGenerator.domain.APIValidator;
import edu.xust.MetadataGenerator.domain.APIValidatorParam;
import edu.xust.MetadataGenerator.domain.Field;
import edu.xust.MetadataGenerator.domain.FieldConstraint;
import edu.xust.MetadataGenerator.domain.FieldValidator;
import edu.xust.MetadataGenerator.domain.FieldValidatorParam;
import edu.xust.MetadataGenerator.domain.MetaData;
import edu.xust.MetadataGenerator.domain.Option;
import edu.xust.MetadataGenerator.domain.Table;
import edu.xust.MetadataGenerator.domain.TableConstraint;
import edu.xust.MetadataGenerator.jxls.domain.Column;
import edu.xust.MetadataGenerator.service.FieldParser;
import edu.xust.MetadataGenerator.service.FieldParserImpl;
import edu.xust.MetadataGenerator.service.MetaDataTreeHelper;
import edu.xust.MetadataGenerator.service.Util;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.event.TreeSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.JTextArea;
import javax.swing.JPanel;
import javax.swing.JLabel;

import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.JTabbedPane;
import javax.swing.JComboBox;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JEditorPane;
import javax.swing.event.CaretListener;
import javax.swing.event.CaretEvent;

import java.awt.Color;
import java.awt.Font;

import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.ListSelectionModel;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.LayoutStyle.ComponentPlacement;

public class Main {

	private static Main _main = null;
	private final static Logger logger = LogManager.getLogger(Main.class);
	private MetaData _metadata;
	private JFrame _frame;
	private JTree _tree;
	private JTabbedPane _tabbedPane;
	private DefaultMutableTreeNode _currentNode = null;
	private String _templateRoot;
	
	private JPanel _panelMetaData;
	private JPanel _panelTable;
	private JPanel _panelField;		
	private JPanel _panelFieldConstraint;		
	private JPanel _panelFieldValidator;
	private JPanel _panelFieldValidatorParameter;		
	private JPanel _panelTableConstraint;		
	private JPanel _panelAPI;		
	private JPanel _panelAPIParam;		
	private JPanel _panelAPIParamValidator;		
	private JPanel _panelAPIParamValidatorParam;		

	private JPopupMenu _menu4MetaData;
	private JPopupMenu _menu4Tables;
	private JPopupMenu _menu4Table;
	
	private JPopupMenu _menu4Fields;
	private JPopupMenu _menu4Field;
	private JPopupMenu _menu4FieldConstraints;
	private JPopupMenu _menu4FieldConstraint;
	private JPopupMenu _menu4FieldValidators;
	private JPopupMenu _menu4FieldValidator;
	private JPopupMenu _menu4FieldValidatorParams;
	private JPopupMenu _menu4FieldValidatorParam;
	private JPopupMenu _menu4TableConstraints;
	private JPopupMenu _menu4TableConstraint;
	
	private JPopupMenu _menu4APIS;
	private JPopupMenu _menu4API;
	private JPopupMenu _menu4APIParams;
	private JPopupMenu _menu4APIParam;
	private JPopupMenu _menu4APIValidators;
	private JPopupMenu _menu4APIValidator;
	private JPopupMenu _menu4APIValidatorParams;
	private JPopupMenu _menu4APIValidatorParam;

	private Map<String, JPopupMenu> _popupMenus;
	private Map<String, Object> _editors;
	
	//Controls fro table
	private JTextField _textFieldTableName;
	private JTextField _textFieldModuleid;
	private JTextField _textFieldTableComment;
	private JComboBox _comboBoxTableTheme;
	
	private JTextField _textFieldGroupid;
	private JTextField _textFieldArtifactid;
	private JTextField _textFieldCopyright;
	private JTextField _textFieldAuthor;
	private JTextField _textFieldVersion;
	private JTextField _textFieldDate;
	private JComboBox _comboBoxDatabase;
	
	//Controls for field
	private JTextField _textFiledFieldName;
	private JComboBox _comboBoxFieldType;
	private JTextField _textFieldLabel;
	
	//Controls for field constraint
	private JComboBox _comboBoxFieldConstraint;
	
	//Controls for field validator
	private JComboBox _comboBoxFieldValidatorType;
	private JTextField _textFieldFieldValidatorMessage;
	private JTextField _textFieldFieldValidatorParamValue;
	private JComboBox _comboBoxFieldValidatorParamName;
	
	//Controls for api
	private JTextField _textFieldApiName;
	private JTextField _textFieldApiReturn;
	private JEditorPane _dtrpnApiDoc;
	
	//Controls for api param
	private JTextField _textFieldApiParamName;
	private JComboBox _comboBoxApiParamType;
	
	//Controls for api validator
	private JComboBox _comboBoxAPIValidatorType;
	private JTextField _textFieldAPIParamValidatorMessage;
	
	private JTextField _textFieldAPIParamValidatorParamName;
	private JTextField _textFieldAPIParamValidatorParamValue;
	private JComboBox _comboBoxAPIParamValidatorParamType;
	private JComboBox _comboBoxTableConstraint;
	private JScrollPane _panelConsole;
	private JTextArea _textAreaConsole;
	private JTextField _textFieldTableSpace;
	private JLabel lblTablePrefix;
	private JTextField _textFieldTablePrefix;
	private JTextField _textFieldComment;
	private JTable _tableValueList;
	private JButton btnDelete;
	private JButton btnSave_1;
	private JMenu mnHelp;
	private JMenuItem mntmAbout;
	private JTextField _sourceRoot;
	private JTextField _outputRoot;
	private JTextField _model;
	private JButton btnImport;
	private JTextField _txtplaceholder;
	private JTextField _txtunit;
	private JTextField _txtdefault;
	private JTextField _textFieldRemoteURL;
	private JTextField _txtArtifacten;
	private JLabel lblAbbr;
	private JTextField _txtAbbr;
	private JButton btnImportexcel;
	private JTextField _textFieldIDFieldName;
	private JTextField _txtEnocding;
	private JComboBox _comboBox_MapType;
	private JTextField _textField_Map_Class;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			@Override
			public void run() {
				try {
					Main window = new Main();
					_main = window;
					window._frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public Main() {
		initialize();
	}

	String captalFirst(String str){
		if(null != str && str.length() > 0){
			str = str.toLowerCase();
			//char[] cs=str.toCharArray();
	        //cs[0] -= 32;
	        //str = String.valueOf(cs);
		}
		
		return str != null ? str : "";
	}
	private String getOracleType(String data_type, Integer data_length, Integer data_precision, Integer data_scale) {
		String type = "varchar(2000)";
		
		String dt = data_type != null ? data_type.toLowerCase() : "varchar";
		if(dt.contains("char") || dt.contains("long")){
			type = "varchar(" + ((data_length != null) ? data_length : 20) + ")";
		}else if(dt.contains("number")){
			if(data_scale == null || data_scale == 0){
				type = "int";
			}else{
				type = "numeric(" + ((data_precision != null) ? data_precision : 10) + "," + data_scale + ")";
			}
		}else if(dt.contains("date") || dt.contains("time")){
			type = "datetime";
		}else if(dt.contains("blob") || dt.contains("cblob")){
			type = "blob";
		}
		
		return type;
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		_frame = new JFrame();
		_frame.setTitle("信息系统代码生成工具");
		_frame.setBounds(100, 100, 1194, 676);
		_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		JMenuBar menuBar = new JMenuBar();
		_frame.setJMenuBar(menuBar);
		
		JMenu mnOpen = new JMenu("File");
		menuBar.add(mnOpen);
		
		JMenuItem mntmOpen = new JMenuItem("Open");
		mntmOpen.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				onOpen();
			}
		});
		mnOpen.add(mntmOpen);
		
		JMenuItem mntmNewMenuItem = new JMenuItem("Save");
		mntmNewMenuItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				onSave();
			}
		});
		mnOpen.add(mntmNewMenuItem);
		
		JMenu mnGenerate = new JMenu("Run");
		menuBar.add(mnGenerate);
		
		JMenuItem mntmGenerate = new JMenuItem("Generate");
		mnGenerate.add(mntmGenerate);
		
		mnHelp = new JMenu("Help");
		menuBar.add(mnHelp);
		
		mntmAbout = new JMenuItem("About");
		mntmAbout.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				try {
					/*
					About dialog = new About();
					dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
					dialog.setLocationRelativeTo(null);
					dialog.setVisible(true);
					*/
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
		mnHelp.add(mntmAbout);
		
		JToolBar toolBar = new JToolBar();
		_frame.getContentPane().add(toolBar, BorderLayout.NORTH);
		
		JButton btnOpen = new JButton("Open");
		btnOpen.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				onOpen();
			}
		});
		toolBar.add(btnOpen);
		
		JButton btnSave = new JButton("Save");
		btnSave.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				onSave();
			}
		});
		
		btnImport = new JButton("Import");
		btnImport.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				JFileChooser fileChooser = new JFileChooser();
				fileChooser.setMultiSelectionEnabled(true);
				FileNameExtensionFilter filter = new FileNameExtensionFilter("Meta data file", "tdd");
				fileChooser.setFileFilter(filter);
				fileChooser.setCurrentDirectory(new File("."));
				fileChooser.setApproveButtonText("Import");
				int returnValue = fileChooser.showDialog(_frame, "Import");
				//int returnValue = fileChooser.showOpenDialog(_frame);

				if (returnValue == JFileChooser.APPROVE_OPTION) {
					File[] files = fileChooser.getSelectedFiles();
					for(File file : files){
						try {
							String json = "";
							logger.debug(file.getAbsolutePath());
							BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "utf-8"));
							String str;
							while((str = bufferedReader.readLine()) != null){
								json += str;
							}
							bufferedReader.close();
							logger.debug(json);
				    		Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
				    		
				    		MetaData metaData = gson.fromJson(json, MetaData.class);
				    		/*
				    		 * Why??????????????
				    		 */
				    		//MetaData metaData = gson.fromJson(bufferReader, MetaData.class);
				    		logger.debug(metaData.getTables().size());
				    		MetaDataTreeHelper.importTables(_tree, metaData);
				    		_tree.updateUI();
						} catch (FileNotFoundException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}	
				selectView(MetaData.CONSOLE);
			}
		});
		toolBar.add(btnImport);
		
		btnImportexcel = new JButton("Import (Excel)");
		btnImportexcel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				JFileChooser fileChooser = new JFileChooser();
				fileChooser.setMultiSelectionEnabled(true);
				FileNameExtensionFilter filter = new FileNameExtensionFilter("Excel file", "xls");
				fileChooser.setFileFilter(filter);
				fileChooser.setCurrentDirectory(new File("."));
				fileChooser.setApproveButtonText("Import");
				int returnValue = fileChooser.showDialog(_frame, "Import");
				//int returnValue = fileChooser.showOpenDialog(_frame);

				if (returnValue == JFileChooser.APPROVE_OPTION) {
					File[] files = fileChooser.getSelectedFiles();
					for(File file : files){
						try {
							String json = "";
							ReaderConfig.getInstance().setSkipErrors( true );
						    String xmlConfig = "/edu/xust/MetadataGenerator/jxls/domain/Column.xml";
					        InputStream xmlInputStream = Main.class.getResourceAsStream(xmlConfig);
					        XLSReader reader = ReaderBuilder.buildFromXML(xmlInputStream);
				            InputStream xlsInputStream = new FileInputStream(file);
			                List<Column> columns = new ArrayList<>();
			                Map<String, Object> beans = new HashMap<>();
			                beans.put("columns", columns);
			                reader.read(xlsInputStream, beans);
			                xlsInputStream.close();
			                logger.info("Read " + (columns != null ? columns.size() : 0) + " column into `columns` list");

			                logger.debug("loadTables...");
			                MetaData md = loadTables(columns);
			                logger.debug("loadTables done!");
				            /*
							BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "GBK"));
							String str;
							while((str = bufferedReader.readLine()) != null){
								json += str;
							}
							bufferedReader.close();
							logger.debug(json);
				    		Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
				    		
				    		MetaData metaData = gson.fromJson(json, MetaData.class);
							
				    		logger.debug(metaData.getTables().size());
							*/
				    		MetaDataTreeHelper.importTables(_tree, md);
				    		_tree.updateUI();
						} catch (Exception e) {
							logger.error(e.getMessage());
						}
					}
				}	
				selectView(MetaData.CONSOLE);
			}

			private MetaData loadTables(List<Column> columns) {
				MetaData md = new MetaData();
				
				logger.debug("Fill table...");
				if(null != columns){
					Map<String, List<Column>> tables_map = new HashMap<String, List<Column>>();
					for(Column col : columns){
						List<Column> cols = null;
						String table_name = col.getTable_name();
						if(tables_map.containsKey(table_name)){
							cols = tables_map.get(table_name); 
						}else{
							cols = new ArrayList<Column>();
						}
						
						cols.add(col);
						tables_map.put(table_name, cols);
					}
					
					List<Table> tables = new ArrayList<Table>();
					for(String key : tables_map.keySet()){
						if(key != null && key.length() > 0){
							Table table = new Table(captalFirst(key));
							List<Field> fields = new ArrayList<Field>();
							List<Column> cols = tables_map.get(key);
							for(Column col : cols){
								if(null != col.getColumn_name()){
									Field field = new Field();
									field.setName(col.getColumn_name().toLowerCase());
									String comment = col.getComments();
									comment = comment != null ? comment : field.getName();
									field.setLabel(comment);
									field.setType(getOracleType(col.getData_type(), col.getData_length(), col.getData_precision(), col.getData_scale()));
									field.setPlaceholder(comment);
									field.setComment(comment);
									
									if(col.getNullable().equalsIgnoreCase("N")){
										List<FieldValidator> fvs = new ArrayList<FieldValidator>();
										FieldValidator fv = new FieldValidator();
										fv.setType("required");
										fvs.add(fv);
										field.setValidators(fvs);
									}
									
									if(col.getIs_pk().equalsIgnoreCase("Y")){
										List<FieldConstraint> fcs = new ArrayList<FieldConstraint>();
										FieldConstraint fc = new FieldConstraint();
										fc.setName("primary key");
										fcs.add(fc);
										field.setConstraints(fcs);
									}
									
									fields.add(field);
								}
							}
							
							table.setFields(fields);
							tables.add(table);
						}
					}
					
					md.setTables(tables);
				}
				logger.debug("Filled table!");
				return md;
			}

		});
		toolBar.add(btnImportexcel);
		toolBar.add(btnSave);
		
		JButton btnGenerate = new JButton("Generate");
		btnGenerate.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				onGenerate();
			}
		});
		toolBar.add(btnGenerate);
		
		JSplitPane splitPane = new JSplitPane();
		_frame.getContentPane().add(splitPane, BorderLayout.CENTER);
		
		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setMinimumSize(new Dimension(300, 600));
		splitPane.setLeftComponent(scrollPane);
		
		_tree = new JTree();
		_tree.setForeground(Color.ORANGE);
		_tree.setBackground(Color.WHITE);
		_tree.addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				if (e.isPopupTrigger()) {
					showMenu(e);
				}
			}
			@Override
			public void mouseReleased(MouseEvent e) {
				if (e.isPopupTrigger()) {
					showMenu(e);
				}
			}
			private void showMenu(MouseEvent e) {
				DefaultMutableTreeNode node =  (DefaultMutableTreeNode)_tree.getLastSelectedPathComponent();
				JPopupMenu menu = null;
				if(null != node){
					Object nodeData = node.getUserObject();
					String menuName = "";
					if("String".equals(nodeData.getClass().getSimpleName())){
						menuName = nodeData.toString();
					}else{
						menuName = nodeData.getClass().getSimpleName();
					}
					logger.debug(menuName);
					menu = _popupMenus.get(menuName);
				}else{
					int count = _tree.getRowCount();
					logger.debug(count);
					if(count == 0){
						menu = _popupMenus.get(MetaData.METADATA);
					}
				}
				if(null != menu){
					menu.show(e.getComponent(), e.getX(), e.getY());
				}
			}
		});
		_tree.addTreeSelectionListener(new TreeSelectionListener() {
			@Override
			public void valueChanged(TreeSelectionEvent arg0) {
				_currentNode =  (DefaultMutableTreeNode)_tree.getLastSelectedPathComponent();
				if(null != _currentNode){
					Object nodeData = _currentNode.getUserObject();
					if(null != nodeData){
						String editorName = nodeData.getClass().getSimpleName();
						selectView(editorName);
						fillControlFromUserData(nodeData);
						/*
						Object editor = null;
						logger.debug(editorName);
						if(!"String".equals(editorName)){
							editor = _editors.get(editorName);
							
						}else{
							editor = _editors.get(MetaData.CONSOLE);
						}
						if(null != editor){
							fillControlFromUserData(nodeData);
							if(editor.getClass().getSimpleName().equals("JScrollPane")){
								_tabbedPane.setSelectedComponent((JScrollPane)editor);
							}else{
								_tabbedPane.setSelectedComponent((JPanel)editor);
							}
							//editor.setVisible(false);
						}
						*/
					}
				}
			}
		});
		_metadata = new MetaData();
		MetaDataTreeHelper.fillTree(_tree, _metadata);
		scrollPane.setViewportView(_tree);
		
		_tabbedPane = new JTabbedPane(SwingConstants.TOP);
		splitPane.setRightComponent(_tabbedPane);
		
		_panelTable = new JPanel();
		
		JLabel lblTableName = new JLabel("Name");
		
		_textFieldTableName = new JTextField();
		_textFieldTableName.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent e) {
				if (_textFieldTableName.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.TABLE.equals(nodeData.getClass().getSimpleName())) {
							((Table) nodeData).setName(_textFieldTableName.getText());
							_tree.repaint();
						}
					}
				}
			}
		});
		_textFieldTableName.setColumns(10);
		
		JLabel lblModuleid = new JLabel("Moduleid");
		
		_textFieldModuleid = new JTextField();
		_textFieldModuleid.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent e) {
				if (_textFieldModuleid.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.TABLE.equals(nodeData.getClass().getSimpleName())) {
							((Table) nodeData).setModuleid(captalFirst(_textFieldModuleid.getText()));
							_tree.repaint();
						}
					}
				}
			}
		});
		_textFieldModuleid.setColumns(10);
		
		JLabel lblTheme = new JLabel("Theme");
		
		_comboBoxTableTheme = new JComboBox();
		_comboBoxTableTheme.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				if (null != _currentNode) {
					Object nodeData = _currentNode.getUserObject();
					if (null != nodeData && MetaData.TABLE.equals(nodeData.getClass().getSimpleName())) {
						((Table) nodeData).setTheme(_comboBoxTableTheme.getSelectedItem().toString());
					}
				}
			}
		});
		_comboBoxTableTheme.setModel(new DefaultComboBoxModel(new String[] {"bootstrap", "black", "metro", "gray", "default"}));
		
		JLabel lblComment = new JLabel("Comment");
		
		_textFieldTableComment = new JTextField();
		_textFieldTableComment.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent e) {
				if (_textFieldTableComment.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.TABLE.equals(nodeData.getClass().getSimpleName())) {
							((Table) nodeData).setComment(_textFieldTableComment.getText());
							_tree.repaint();
						}
					}
				}
			}
		});
		_textFieldTableComment.setColumns(10);
		
		_panelFieldConstraint = new JPanel();
		
		JLabel lblConstraint = new JLabel("Constraint");
		
		_panelFieldValidator = new JPanel();
		
		JLabel lblType = new JLabel("Type");
		
		_comboBoxFieldValidatorType = new JComboBox();
		_comboBoxFieldValidatorType.setModel(new DefaultComboBoxModel(new String[] {"required", "requiredstring", "stringlength", "int", "double", "date", "email", "url", "fieldexpression", "expression", "visitor", "regex"}));
		_comboBoxFieldValidatorType.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (null != _currentNode) {
					Object nodeData = _currentNode.getUserObject();
					if (null != nodeData && MetaData.FIELDVALIDATOR.equals(nodeData.getClass().getSimpleName())) {
						((FieldValidator) nodeData).setType(_comboBoxFieldValidatorType.getSelectedItem().toString());
						_textFieldFieldValidatorMessage.setText(((FieldValidator) nodeData).getMessage());
						_tree.repaint();
					}
				}
			}
		});
		_comboBoxFieldValidatorType.setEditable(true);
		
		JLabel lblMessage = new JLabel("Message");
		
		_textFieldFieldValidatorMessage = new JTextField();
		_textFieldFieldValidatorMessage.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent e) {
				if (_textFieldFieldValidatorMessage.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.FIELDVALIDATOR.equals(nodeData.getClass().getSimpleName())) {
							((FieldValidator) nodeData).setMessage(_textFieldFieldValidatorMessage.getText());
							_tree.repaint();
						}
					}
				}
			}
		});
		_textFieldFieldValidatorMessage.setText("Message");
		_textFieldFieldValidatorMessage.setColumns(10);
		
		_panelFieldValidatorParameter = new JPanel();
		
		JLabel lblValue = new JLabel("Value");
		
		_textFieldFieldValidatorParamValue = new JTextField();
		_textFieldFieldValidatorParamValue.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent e) {
				if (_textFieldFieldValidatorParamValue.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.FIELDVALIDATORPARAM.equals(nodeData.getClass().getSimpleName())) {
							((FieldValidatorParam) nodeData).setValue(_textFieldFieldValidatorParamValue.getText());
							_tree.repaint();
						}
					}
				}
			}
		});
		_textFieldFieldValidatorParamValue.setText("FieldValidatorParamValue");
		_textFieldFieldValidatorParamValue.setColumns(10);
		
		JLabel lblName = new JLabel("Name");
		
		_comboBoxFieldValidatorParamName = new JComboBox();
		_comboBoxFieldValidatorParamName.setModel(new DefaultComboBoxModel(new String[] {"trim", "minLength", "maxLength", "min", "max", "minInclusive", "maxInclusive", "minExclusive", "maxExclusive", "expression"}));
		_comboBoxFieldValidatorParamName.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (null != _currentNode) {
					Object nodeData = _currentNode.getUserObject();
					if (null != nodeData && MetaData.FIELDVALIDATORPARAM.equals(nodeData.getClass().getSimpleName())) {
						((FieldValidatorParam) nodeData).setName(_comboBoxFieldValidatorParamName.getSelectedItem().toString());
						_tree.repaint();
					}
				}
			}
		});
		_comboBoxFieldValidatorParamName.setEditable(true);
		
		_panelTableConstraint = new JPanel();
		
		JLabel lblConstraint_1 = new JLabel("Constraint");
		
		_panelAPI = new JPanel();
		
		JLabel lblName_1 = new JLabel("Name");
		
		_textFieldApiName = new JTextField();
		_textFieldApiName.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent e) {
				if (_textFieldApiName.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.API.equals(nodeData.getClass().getSimpleName())) {
							((API) nodeData).setName(_textFieldApiName.getText());
							_tree.repaint();
						}
					}
				}
			}
		});
		_textFieldApiName.setText("APIName");
		_textFieldApiName.setColumns(10);
		
		JLabel lblReturn = new JLabel("Return");
		lblReturn.setToolTipText("The description of return value of specified api.");
		
		_textFieldApiReturn = new JTextField();
		_textFieldApiReturn.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent e) {
				if (_textFieldApiReturn.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.API.equals(nodeData.getClass().getSimpleName())) {
							((API) nodeData).setReturn(_textFieldApiReturn.getText());
							_tree.repaint();
						}
					}
				}
			}
		});
		_textFieldApiReturn.setText("APIReturn");
		_textFieldApiReturn.setColumns(10);
		
		JLabel lblComment_1 = new JLabel("Comment");
		
		_dtrpnApiDoc = new JEditorPane();
		_dtrpnApiDoc.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent e) {
				if (_dtrpnApiDoc.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.API.equals(nodeData.getClass().getSimpleName())) {
							((API) nodeData).setDoc(_dtrpnApiDoc.getText());
							_tree.repaint();
						}
					}
				}
			}
		});
		_dtrpnApiDoc.setText("APIDoc");
		
		_panelAPIParam = new JPanel();
		
		JLabel lblName_2 = new JLabel("Name");
		
		JLabel lblType_2 = new JLabel("Type");
		
		_textFieldApiParamName = new JTextField();
		_textFieldApiParamName.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent e) {
				if (_textFieldApiParamName.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.APIPARAM.equals(nodeData.getClass().getSimpleName())) {
							((APIParam) nodeData).setName(_textFieldApiParamName.getText());
							_tree.repaint();
						}
					}
				}
			}
		});
		_textFieldApiParamName.setText("APIParamName");
		_textFieldApiParamName.setColumns(10);
		
		_panelAPIParamValidator = new JPanel();
		
		JLabel label = new JLabel("Type");
		
		_comboBoxAPIValidatorType = new JComboBox();
		_comboBoxAPIValidatorType.setModel(new DefaultComboBoxModel(new String[] {"required", "requiedstring", "stringlength", "int", "double", "date", "email", "url", "fieldexpression", "expression", "visitor", "regex"}));
		_comboBoxAPIValidatorType.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (null != _currentNode) {
					Object nodeData = _currentNode.getUserObject();
					if (null != nodeData && MetaData.APIVALIDATOR.equals(nodeData.getClass().getSimpleName())) {
						((APIValidator) nodeData).setType(_comboBoxAPIValidatorType.getSelectedItem().toString());
						_textFieldAPIParamValidatorMessage.setText(((APIValidator) nodeData).getMessage());
						_tree.repaint();
					}
				}
			}
		});
		_comboBoxAPIValidatorType.setEditable(true);
		
		JLabel label_1 = new JLabel("Message");
		
		_textFieldAPIParamValidatorMessage = new JTextField();
		_textFieldAPIParamValidatorMessage.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent e) {
				if (_textFieldAPIParamValidatorMessage.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.APIVALIDATOR.equals(nodeData.getClass().getSimpleName())) {
							((APIValidator) nodeData).setMessage(_textFieldAPIParamValidatorMessage.getText());
						}
					}
				}
			}
		});
		_textFieldAPIParamValidatorMessage.setText("Message");
		_textFieldAPIParamValidatorMessage.setColumns(10);
		
		_panelAPIParamValidatorParam = new JPanel();
		
		JLabel label_2 = new JLabel("Name");
		
		_textFieldAPIParamValidatorParamName = new JTextField();
		_textFieldAPIParamValidatorParamName.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent e) {
				if (_textFieldAPIParamValidatorParamName.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.APIVALIDATORPARAM.equals(nodeData.getClass().getSimpleName())) {
							((APIValidatorParam) nodeData).setName(_textFieldAPIParamValidatorParamName.getText());
							_tree.repaint();
						}
					}
				}
			}
		});
		_textFieldAPIParamValidatorParamName.setText("APIParamValidatorParamName");
		_textFieldAPIParamValidatorParamName.setColumns(10);
		
		JLabel label_3 = new JLabel("Value");
		
		_textFieldAPIParamValidatorParamValue = new JTextField();
		_textFieldAPIParamValidatorParamValue.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent e) {
				if (_textFieldAPIParamValidatorParamValue.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.APIVALIDATORPARAM.equals(nodeData.getClass().getSimpleName())) {
							((APIValidatorParam) nodeData).setValue(_textFieldAPIParamValidatorParamValue.getText());
							_tree.repaint();
						}
					}
				}
			}
		});
		_textFieldAPIParamValidatorParamValue.setText("APIParamValidatorParamValue");
		_textFieldAPIParamValidatorParamValue.setColumns(10);
		
		JLabel label_4 = new JLabel("Type");
		
		_comboBoxAPIParamValidatorParamType = new JComboBox();
		_comboBoxAPIParamValidatorParamType.setModel(new DefaultComboBoxModel(new String[] {"trim", "minLength", "maxLength", "min", "max", "minInclusive", "maxInclusive", "minExclusive", "maxExclusive", "expression"}));
		_comboBoxAPIParamValidatorParamType.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				Object nodeData = _currentNode.getUserObject();
				if (null != nodeData && MetaData.APIVALIDATORPARAM.equals(nodeData.getClass().getSimpleName())) {
					((APIValidatorParam) nodeData).setType(_comboBoxAPIParamValidatorParamType.getSelectedItem().toString());
				}
			}
		});
		_comboBoxAPIParamValidatorParamType.setEditable(true);
		
		_panelConsole = new JScrollPane();
		_tabbedPane.addTab("Console", null, _panelConsole, null);
		
		_textAreaConsole = new JTextArea();
		_textAreaConsole.setText("Console");
		_textAreaConsole.setLineWrap(true);
		_textAreaConsole.setForeground(Color.ORANGE);
		_textAreaConsole.setFont(new Font("Dialog", Font.PLAIN, 16));
		_textAreaConsole.setBackground(Color.DARK_GRAY);
		_panelConsole.setViewportView(_textAreaConsole);
		
		_panelMetaData = new JPanel();
		
		JLabel lblGroupid = new JLabel("Groupid");
		
		JLabel lblAritfactid = new JLabel("Aritfactid");
		
		JLabel lblCopyright = new JLabel("Copyright");
		
		JLabel lblAuthor = new JLabel("Author");
		
		JLabel lblVersion = new JLabel("Version");
		
		JLabel lblDatabase = new JLabel("Database");
		
		JLabel lblDate = new JLabel("Date");
		
		_textFieldGroupid = new JTextField();
		_textFieldGroupid.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent arg0) {
				if (_textFieldGroupid.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.METADATA.equals(nodeData.getClass().getSimpleName())) {
							((MetaData) nodeData).setGroupid(_textFieldGroupid.getText());
							_tree.repaint();
						}
					}
				}
			}
		});
		_textFieldGroupid.setColumns(10);
		
		_textFieldArtifactid = new JTextField();
		_textFieldArtifactid.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent e) {
				if (_textFieldArtifactid.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.METADATA.equals(nodeData.getClass().getSimpleName())) {
							((MetaData) nodeData).setArtifactid(_textFieldArtifactid.getText());
							_tree.repaint();
						}
					}
				}
			}
		});
		_textFieldArtifactid.setColumns(10);
		
		_textFieldCopyright = new JTextField();
		_textFieldCopyright.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent e) {
				if (_textFieldCopyright.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.METADATA.equals(nodeData.getClass().getSimpleName())) {
							((MetaData) nodeData).setCopyright(_textFieldCopyright.getText());
							_tree.repaint();
						}
					}
				}
			}
		});
		_textFieldCopyright.setColumns(10);
		
		_textFieldAuthor = new JTextField();
		_textFieldAuthor.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent e) {
				if (_textFieldAuthor.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.METADATA.equals(nodeData.getClass().getSimpleName())) {
							((MetaData) nodeData).setAuthor(_textFieldAuthor.getText());
							_tree.repaint();
						}
					}
				}
			}
		});
		_textFieldAuthor.setColumns(10);
		
		_textFieldVersion = new JTextField();
		_textFieldVersion.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent e) {
				if (_textFieldVersion.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.METADATA.equals(nodeData.getClass().getSimpleName())) {
							((MetaData) nodeData).setVersion(_textFieldVersion.getText());
							_tree.repaint();
						}
					}
				}
			}
		});
		_textFieldVersion.setColumns(10);
		
		_textFieldDate = new JTextField();
		_textFieldDate.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent e) {
				if (_textFieldDate.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.METADATA.equals(nodeData.getClass().getSimpleName())) {
							((MetaData) nodeData).setDate(_textFieldDate.getText());
							_tree.repaint();
						}
					}
				}
			}
		});
		_textFieldDate.setText("");
		_textFieldDate.setColumns(10);
		
			_tabbedPane.addTab("Meta Data", null, _panelMetaData, null);
			
			_comboBoxDatabase = new JComboBox();
			_comboBoxDatabase.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					Object nodeData = _currentNode.getUserObject();
					if (null != nodeData && MetaData.METADATA.equals(nodeData.getClass().getSimpleName())) {
						((MetaData) nodeData).setDatabase(_comboBoxDatabase.getSelectedItem().toString());
					}
				}
			});
			_comboBoxDatabase.setModel(new DefaultComboBoxModel(new String[] {"oracle", "mssql", "mysql", "db2", "postgreSQL"}));
			
			JLabel lblTableSpace = new JLabel("Table Space");
			
			_textFieldTableSpace = new JTextField();
			_textFieldTableSpace.addCaretListener(new CaretListener() {
				@Override
				public void caretUpdate(CaretEvent arg0) {
					if (_textFieldTableSpace.isFocusOwner()) {
						if (null != _currentNode) {
							Object nodeData = _currentNode.getUserObject();
							if (null != nodeData && MetaData.METADATA.equals(nodeData.getClass().getSimpleName())) {
								((MetaData) nodeData).setTableSpace(_textFieldTableSpace.getText());
								_tree.repaint();
							}
						}
					}
				}
			});
			_textFieldTableSpace.setColumns(10);
			
			lblTablePrefix = new JLabel("Table Prefix");
			
			_textFieldTablePrefix = new JTextField();
			_textFieldTablePrefix.addCaretListener(new CaretListener() {
				@Override
				public void caretUpdate(CaretEvent arg0) {
					if (_textFieldTablePrefix.isFocusOwner()) {
						if (null != _currentNode) {
							Object nodeData = _currentNode.getUserObject();
							if (null != nodeData && MetaData.METADATA.equals(nodeData.getClass().getSimpleName())) {
								((MetaData) nodeData).setTablePrefix(_textFieldTablePrefix.getText());
								_tree.repaint();
							}
						}
					}
				}
			});
			_textFieldTablePrefix.setColumns(10);
			
			JLabel lblSourceRoot = new JLabel("Source Root");
			
			_sourceRoot = new JTextField();
			_sourceRoot.setEditable(false);
			_sourceRoot.addCaretListener(new CaretListener() {
				@Override
				public void caretUpdate(CaretEvent arg0) {
					if (_sourceRoot.isFocusOwner()) {
						if (null != _currentNode) {
							Object nodeData = _currentNode.getUserObject();
							if (null != nodeData && MetaData.METADATA.equals(nodeData.getClass().getSimpleName())) {
								((MetaData) nodeData).setSourceRoot(_sourceRoot.getText());
								_tree.repaint();
							}
						}
					}
				}
			});
			_sourceRoot.setText("");
			_sourceRoot.setColumns(10);
			
			JLabel lblOutputRoot = new JLabel("Output Root");
			
			_outputRoot = new JTextField();
			_outputRoot.setEditable(false);
			_outputRoot.setText("");
			_outputRoot.setColumns(10);
			
			JLabel lblModel = new JLabel("Model");
			
			_model = new JTextField();
			_model.setEditable(false);
			_model.setText("");
			_model.setColumns(10);
			
			JButton buttonSource = new JButton("...");
			buttonSource.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent arg0) {
					JFileChooser fileChooser = new JFileChooser(".");
					fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
					int returnVal = fileChooser.showOpenDialog(fileChooser);
					if (returnVal == JFileChooser.APPROVE_OPTION) {
						String path = fileChooser.getSelectedFile().getAbsolutePath();
						_sourceRoot.setText(path);
						if (null != _currentNode) {
							Object nodeData = _currentNode.getUserObject();
							if (null != nodeData && MetaData.METADATA.equals(nodeData.getClass().getSimpleName())) {
								((MetaData) nodeData).setSourceRoot(path);
								_tree.repaint();
							}
						}

					}
				}
			});
			
			JButton buttonOutput = new JButton("...");
			buttonOutput.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					JFileChooser fileChooser = new JFileChooser(".");
					fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
					int returnVal = fileChooser.showOpenDialog(fileChooser);
					if (returnVal == JFileChooser.APPROVE_OPTION) {
						String path = fileChooser.getSelectedFile().getAbsolutePath();
						_outputRoot.setText(path);
						if (null != _currentNode) {
							Object nodeData = _currentNode.getUserObject();
							if (null != nodeData && MetaData.METADATA.equals(nodeData.getClass().getSimpleName())) {
								((MetaData) nodeData).setOutputRoot(path);
								_tree.repaint();
							}
						}
					}
				}
			});
			
			JButton buttonModel = new JButton("...");
			buttonModel.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) {
					JFileChooser fileChooser = new JFileChooser();
					FileNameExtensionFilter filter = new FileNameExtensionFilter("Meta data file", "tdd");
					fileChooser.setFileFilter(filter);
					
					fileChooser.setCurrentDirectory(new File(_sourceRoot.getText() + "/data"));
					int returnValue = fileChooser.showOpenDialog(_frame);

					if (returnValue == JFileChooser.APPROVE_OPTION) {
						File file = fileChooser.getSelectedFile();
						_model.setText(file.getName());
						if (null != _currentNode) {
							Object nodeData = _currentNode.getUserObject();
							if (null != nodeData && MetaData.METADATA.equals(nodeData.getClass().getSimpleName())) {
								((MetaData) nodeData).setModel(file.getName());
								_tree.repaint();
							}
						}
					}
				}
			});
			
			_txtArtifacten = new JTextField();
			_txtArtifacten.addCaretListener(new CaretListener() {
				@Override
				public void caretUpdate(CaretEvent arg0) {
					if (_txtArtifacten.isFocusOwner()) {
						if (null != _currentNode) {
							Object nodeData = _currentNode.getUserObject();
							if (null != nodeData && MetaData.METADATA.equals(nodeData.getClass().getSimpleName())) {
								((MetaData) nodeData).setArtifactid_en(_txtArtifacten.getText());
								_tree.repaint();
							}
						}
					}
				}
			});
			_txtArtifacten.setColumns(10);
			
			JLabel lblArtifactiden = new JLabel("Artifactid_en");
			
			lblAbbr = new JLabel("abbr");
			
			_txtAbbr = new JTextField();
			_txtAbbr.addCaretListener(new CaretListener() {
				@Override
				public void caretUpdate(CaretEvent arg0) {
					if (_txtAbbr.isFocusOwner()) {
						if (null != _currentNode) {
							Object nodeData = _currentNode.getUserObject();
							if (null != nodeData && MetaData.METADATA.equals(nodeData.getClass().getSimpleName())) {
								((MetaData) nodeData).setArtifactid_en_abbr(_txtAbbr.getText());
								_tree.repaint();
							}
						}
					}
				}
			});
			_txtAbbr.setColumns(10);
			
			JLabel lblEncoding = new JLabel("Encoding");
			
			_txtEnocding = new JTextField();
			_txtEnocding.addCaretListener(new CaretListener() {
				public void caretUpdate(CaretEvent arg0) {
					if (_txtEnocding.isFocusOwner()) {
						if (null != _currentNode) {
							Object nodeData = _currentNode.getUserObject();
							if (null != nodeData && MetaData.METADATA.equals(nodeData.getClass().getSimpleName())) {
								((MetaData) nodeData).setEncoding(_txtEnocding.getText());
								_tree.repaint();
							}
						}
					}
				}
			});
			_txtEnocding.setText("gbk");
			_txtEnocding.setColumns(10);
			GroupLayout gl__panelMetaData = new GroupLayout(_panelMetaData);
			gl__panelMetaData.setHorizontalGroup(
				gl__panelMetaData.createParallelGroup(Alignment.LEADING)
					.addGroup(Alignment.TRAILING, gl__panelMetaData.createSequentialGroup()
						.addContainerGap()
						.addGroup(gl__panelMetaData.createParallelGroup(Alignment.LEADING)
							.addGroup(gl__panelMetaData.createParallelGroup(Alignment.LEADING)
								.addGroup(gl__panelMetaData.createSequentialGroup()
									.addComponent(lblAbbr, GroupLayout.DEFAULT_SIZE, 104, Short.MAX_VALUE)
									.addPreferredGap(ComponentPlacement.RELATED))
								.addGroup(gl__panelMetaData.createSequentialGroup()
									.addComponent(lblDate, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
									.addPreferredGap(ComponentPlacement.RELATED))
								.addGroup(gl__panelMetaData.createSequentialGroup()
									.addComponent(lblTablePrefix, GroupLayout.PREFERRED_SIZE, 70, GroupLayout.PREFERRED_SIZE)
									.addPreferredGap(ComponentPlacement.RELATED))
								.addGroup(gl__panelMetaData.createSequentialGroup()
									.addGroup(gl__panelMetaData.createParallelGroup(Alignment.LEADING)
										.addGroup(gl__panelMetaData.createSequentialGroup()
											.addComponent(lblModel, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
											.addGap(27))
										.addComponent(lblSourceRoot, GroupLayout.DEFAULT_SIZE, 104, Short.MAX_VALUE)
										.addComponent(lblOutputRoot, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 104, Short.MAX_VALUE)
										.addComponent(lblArtifactiden, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
										.addGroup(gl__panelMetaData.createSequentialGroup()
											.addComponent(lblDatabase, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
											.addGap(27))
										.addGroup(gl__panelMetaData.createSequentialGroup()
											.addComponent(lblVersion, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
											.addGap(27))
										.addGroup(gl__panelMetaData.createSequentialGroup()
											.addComponent(lblAuthor, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
											.addGap(27))
										.addGroup(gl__panelMetaData.createSequentialGroup()
											.addComponent(lblCopyright, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
											.addGap(27))
										.addComponent(lblTableSpace, GroupLayout.PREFERRED_SIZE, 70, GroupLayout.PREFERRED_SIZE))
									.addPreferredGap(ComponentPlacement.RELATED))
								.addGroup(gl__panelMetaData.createSequentialGroup()
									.addComponent(lblAritfactid, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
									.addGap(27))
								.addGroup(gl__panelMetaData.createSequentialGroup()
									.addComponent(lblGroupid, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
									.addGap(27)))
							.addGroup(gl__panelMetaData.createSequentialGroup()
								.addComponent(lblEncoding)
								.addPreferredGap(ComponentPlacement.RELATED)))
						.addGroup(gl__panelMetaData.createParallelGroup(Alignment.LEADING)
							.addComponent(_txtEnocding, GroupLayout.DEFAULT_SIZE, 740, Short.MAX_VALUE)
							.addComponent(_textFieldArtifactid, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 740, Short.MAX_VALUE)
							.addComponent(_txtArtifacten, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 740, Short.MAX_VALUE)
							.addComponent(_txtAbbr, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 740, Short.MAX_VALUE)
							.addComponent(_textFieldCopyright, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 740, Short.MAX_VALUE)
							.addComponent(_textFieldDate, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 740, Short.MAX_VALUE)
							.addComponent(_textFieldAuthor, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 740, Short.MAX_VALUE)
							.addComponent(_textFieldVersion, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 740, Short.MAX_VALUE)
							.addComponent(_textFieldTableSpace, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 740, Short.MAX_VALUE)
							.addComponent(_textFieldTablePrefix, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 740, Short.MAX_VALUE)
							.addComponent(_comboBoxDatabase, Alignment.TRAILING, 0, 740, Short.MAX_VALUE)
							.addGroup(Alignment.TRAILING, gl__panelMetaData.createSequentialGroup()
								.addComponent(_sourceRoot, GroupLayout.DEFAULT_SIZE, 687, Short.MAX_VALUE)
								.addPreferredGap(ComponentPlacement.RELATED)
								.addComponent(buttonSource, GroupLayout.PREFERRED_SIZE, 45, GroupLayout.PREFERRED_SIZE))
							.addGroup(Alignment.TRAILING, gl__panelMetaData.createSequentialGroup()
								.addComponent(_model, GroupLayout.DEFAULT_SIZE, 687, Short.MAX_VALUE)
								.addPreferredGap(ComponentPlacement.RELATED)
								.addComponent(buttonModel, GroupLayout.PREFERRED_SIZE, 45, GroupLayout.PREFERRED_SIZE))
							.addGroup(Alignment.TRAILING, gl__panelMetaData.createSequentialGroup()
								.addComponent(_outputRoot, GroupLayout.DEFAULT_SIZE, 687, Short.MAX_VALUE)
								.addPreferredGap(ComponentPlacement.RELATED)
								.addComponent(buttonOutput, GroupLayout.PREFERRED_SIZE, 45, GroupLayout.PREFERRED_SIZE))
							.addGroup(Alignment.TRAILING, gl__panelMetaData.createSequentialGroup()
								.addPreferredGap(ComponentPlacement.RELATED)
								.addComponent(_textFieldGroupid, GroupLayout.DEFAULT_SIZE, 740, Short.MAX_VALUE)))
						.addGap(0))
			);
			gl__panelMetaData.setVerticalGroup(
				gl__panelMetaData.createParallelGroup(Alignment.LEADING)
					.addGroup(gl__panelMetaData.createSequentialGroup()
						.addGap(12)
						.addGroup(gl__panelMetaData.createParallelGroup(Alignment.BASELINE)
							.addComponent(lblGroupid)
							.addComponent(_textFieldGroupid, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE))
						.addPreferredGap(ComponentPlacement.RELATED)
						.addGroup(gl__panelMetaData.createParallelGroup(Alignment.LEADING)
							.addGroup(gl__panelMetaData.createSequentialGroup()
								.addGap(10)
								.addComponent(lblAritfactid))
							.addGroup(gl__panelMetaData.createSequentialGroup()
								.addGap(8)
								.addComponent(_textFieldArtifactid, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)))
						.addPreferredGap(ComponentPlacement.RELATED)
						.addGroup(gl__panelMetaData.createParallelGroup(Alignment.BASELINE)
							.addComponent(_txtArtifacten, GroupLayout.PREFERRED_SIZE, 24, GroupLayout.PREFERRED_SIZE)
							.addComponent(lblArtifactiden))
						.addGap(11)
						.addGroup(gl__panelMetaData.createParallelGroup(Alignment.BASELINE)
							.addComponent(_txtAbbr, GroupLayout.PREFERRED_SIZE, 23, GroupLayout.PREFERRED_SIZE)
							.addComponent(lblAbbr))
						.addPreferredGap(ComponentPlacement.RELATED)
						.addGroup(gl__panelMetaData.createParallelGroup(Alignment.BASELINE)
							.addComponent(lblCopyright)
							.addComponent(_textFieldCopyright, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE))
						.addPreferredGap(ComponentPlacement.RELATED)
						.addGroup(gl__panelMetaData.createParallelGroup(Alignment.LEADING)
							.addGroup(gl__panelMetaData.createSequentialGroup()
								.addGap(10)
								.addComponent(lblAuthor))
							.addGroup(gl__panelMetaData.createSequentialGroup()
								.addGap(8)
								.addComponent(_textFieldAuthor, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)))
						.addPreferredGap(ComponentPlacement.RELATED)
						.addGroup(gl__panelMetaData.createParallelGroup(Alignment.LEADING)
							.addGroup(gl__panelMetaData.createSequentialGroup()
								.addGap(10)
								.addComponent(lblVersion))
							.addGroup(gl__panelMetaData.createSequentialGroup()
								.addGap(8)
								.addComponent(_textFieldVersion, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)))
						.addGap(8)
						.addGroup(gl__panelMetaData.createParallelGroup(Alignment.BASELINE)
							.addComponent(_textFieldTableSpace, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)
							.addComponent(lblTableSpace))
						.addGap(8)
						.addGroup(gl__panelMetaData.createParallelGroup(Alignment.BASELINE)
							.addComponent(_textFieldTablePrefix, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)
							.addComponent(lblTablePrefix))
						.addPreferredGap(ComponentPlacement.RELATED)
						.addGroup(gl__panelMetaData.createParallelGroup(Alignment.LEADING)
							.addGroup(gl__panelMetaData.createSequentialGroup()
								.addGap(14)
								.addComponent(lblDatabase)
								.addGap(14))
							.addGroup(gl__panelMetaData.createSequentialGroup()
								.addGap(10)
								.addComponent(_comboBoxDatabase, GroupLayout.PREFERRED_SIZE, 27, GroupLayout.PREFERRED_SIZE)))
						.addPreferredGap(ComponentPlacement.RELATED)
						.addGroup(gl__panelMetaData.createParallelGroup(Alignment.BASELINE)
							.addComponent(lblEncoding)
							.addComponent(_txtEnocding, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
						.addPreferredGap(ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
						.addGroup(gl__panelMetaData.createParallelGroup(Alignment.BASELINE)
							.addComponent(_textFieldDate, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)
							.addComponent(lblDate))
						.addPreferredGap(ComponentPlacement.RELATED)
						.addGroup(gl__panelMetaData.createParallelGroup(Alignment.LEADING)
							.addGroup(gl__panelMetaData.createSequentialGroup()
								.addGap(12)
								.addGroup(gl__panelMetaData.createParallelGroup(Alignment.BASELINE)
									.addComponent(_sourceRoot, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)
									.addComponent(buttonSource, GroupLayout.PREFERRED_SIZE, 27, GroupLayout.PREFERRED_SIZE)))
							.addGroup(gl__panelMetaData.createSequentialGroup()
								.addGap(14)
								.addComponent(lblSourceRoot)))
						.addPreferredGap(ComponentPlacement.RELATED)
						.addGroup(gl__panelMetaData.createParallelGroup(Alignment.LEADING)
							.addGroup(gl__panelMetaData.createSequentialGroup()
								.addGap(14)
								.addComponent(lblOutputRoot))
							.addGroup(gl__panelMetaData.createSequentialGroup()
								.addGap(12)
								.addGroup(gl__panelMetaData.createParallelGroup(Alignment.BASELINE)
									.addComponent(_outputRoot, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)
									.addComponent(buttonOutput, GroupLayout.PREFERRED_SIZE, 27, GroupLayout.PREFERRED_SIZE))))
						.addGroup(gl__panelMetaData.createParallelGroup(Alignment.LEADING)
							.addGroup(gl__panelMetaData.createSequentialGroup()
								.addGap(14)
								.addComponent(lblModel))
							.addGroup(gl__panelMetaData.createSequentialGroup()
								.addGap(12)
								.addGroup(gl__panelMetaData.createParallelGroup(Alignment.BASELINE)
									.addComponent(_model, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)
									.addComponent(buttonModel, GroupLayout.PREFERRED_SIZE, 27, GroupLayout.PREFERRED_SIZE))))
						.addGap(47))
			);
			_panelMetaData.setLayout(gl__panelMetaData);
		_tabbedPane.addTab("Table", null, _panelTable, null);
		
		_textFieldIDFieldName = new JTextField();
		_textFieldIDFieldName.addCaretListener(new CaretListener() {
			public void caretUpdate(CaretEvent arg0) {
				if (null != _currentNode) {
					Object nodeData = _currentNode.getUserObject();
					if (null != nodeData && MetaData.TABLE.equals(nodeData.getClass().getSimpleName())) {
						((Table) nodeData).setIdFieldName(_textFieldIDFieldName.getText());
						_tree.repaint();
					}
				}
			}
		});
		_textFieldIDFieldName.setColumns(10);
		
		JLabel lblIdField = new JLabel("ID field");
		GroupLayout gl__panelTable = new GroupLayout(_panelTable);
		gl__panelTable.setHorizontalGroup(
			gl__panelTable.createParallelGroup(Alignment.LEADING)
				.addGroup(gl__panelTable.createSequentialGroup()
					.addGap(12)
					.addGroup(gl__panelTable.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelTable.createSequentialGroup()
							.addComponent(lblTableName, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
							.addGap(18)
							.addComponent(_textFieldTableName, GroupLayout.DEFAULT_SIZE, 771, Short.MAX_VALUE))
						.addGroup(gl__panelTable.createSequentialGroup()
							.addComponent(lblModuleid, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
							.addGap(18)
							.addComponent(_textFieldModuleid, GroupLayout.DEFAULT_SIZE, 771, Short.MAX_VALUE))
						.addGroup(gl__panelTable.createSequentialGroup()
							.addComponent(lblTheme, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
							.addGap(18)
							.addComponent(_comboBoxTableTheme, 0, 771, Short.MAX_VALUE))
						.addGroup(gl__panelTable.createSequentialGroup()
							.addGroup(gl__panelTable.createParallelGroup(Alignment.LEADING)
								.addComponent(lblComment)
								.addComponent(lblIdField))
							.addGap(12)
							.addGroup(gl__panelTable.createParallelGroup(Alignment.LEADING)
								.addGroup(gl__panelTable.createSequentialGroup()
									.addGap(10)
									.addComponent(_textFieldIDFieldName, GroupLayout.DEFAULT_SIZE, 774, Short.MAX_VALUE))
								.addComponent(_textFieldTableComment, GroupLayout.DEFAULT_SIZE, 784, Short.MAX_VALUE))))
					.addContainerGap())
		);
		gl__panelTable.setVerticalGroup(
			gl__panelTable.createParallelGroup(Alignment.LEADING)
				.addGroup(gl__panelTable.createSequentialGroup()
					.addGroup(gl__panelTable.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelTable.createSequentialGroup()
							.addGap(12)
							.addComponent(lblTableName))
						.addGroup(gl__panelTable.createSequentialGroup()
							.addGap(10)
							.addComponent(_textFieldTableName, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)))
					.addGroup(gl__panelTable.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelTable.createSequentialGroup()
							.addGap(14)
							.addComponent(lblModuleid))
						.addGroup(gl__panelTable.createSequentialGroup()
							.addGap(12)
							.addComponent(_textFieldModuleid, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)))
					.addGroup(gl__panelTable.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelTable.createSequentialGroup()
							.addGap(16)
							.addComponent(lblTheme))
						.addGroup(gl__panelTable.createSequentialGroup()
							.addGap(12)
							.addComponent(_comboBoxTableTheme, GroupLayout.PREFERRED_SIZE, 27, GroupLayout.PREFERRED_SIZE)))
					.addGroup(gl__panelTable.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelTable.createSequentialGroup()
							.addGap(14)
							.addComponent(lblComment))
						.addGroup(gl__panelTable.createSequentialGroup()
							.addGap(12)
							.addComponent(_textFieldTableComment, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)))
					.addPreferredGap(ComponentPlacement.UNRELATED)
					.addGroup(gl__panelTable.createParallelGroup(Alignment.BASELINE)
						.addComponent(_textFieldIDFieldName, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
						.addComponent(lblIdField))
					.addContainerGap(375, Short.MAX_VALUE))
		);
		_panelTable.setLayout(gl__panelTable);
		
		_panelField = new JPanel();
		
		JLabel lblName_3 = new JLabel("Name");
		
		_textFiledFieldName = new JTextField();
		_textFiledFieldName.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent e) {
				if (_textFiledFieldName.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.FIELD.equals(nodeData.getClass().getSimpleName())) {
							((Field) nodeData).setName(_textFiledFieldName.getText());
							_tree.repaint();
						}
					}
				}
			}
		});
		_textFiledFieldName.setText("FieldName");
		_textFiledFieldName.setColumns(10);
		
		JLabel lblType_3 = new JLabel("Comment");
		
		_comboBoxFieldType = new JComboBox();
		_comboBoxFieldType.setModel(new DefaultComboBoxModel(new String[] {"int", "int(size)", "integer(10)", "smallint(10)", "tinyint(10)", "decimal(10,5)", "numeric(10,5)", "char(20)", "varchar(20)", "date", "datetime", "blob"}));
		_comboBoxFieldType.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				if (null != _currentNode) {
					Object nodeData = _currentNode.getUserObject();
					if (null != nodeData && MetaData.FIELD.equals(nodeData.getClass().getSimpleName())) {
						((Field) nodeData).setType(_comboBoxFieldType.getSelectedItem().toString());
					}
				}
			}
		});
		_comboBoxFieldType.setEditable(true);
		_tabbedPane.addTab("Field", null, _panelField, null);
		
		_textFieldLabel = new JTextField();
		_textFieldLabel.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent arg0) {
				if (_textFieldLabel.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.FIELD.equals(nodeData.getClass().getSimpleName())) {
							Field field = (Field) nodeData;
							field.setLabel(_textFieldLabel.getText());
							_textFieldComment.setText(_textFieldLabel.getText());
							field.setComment(_textFieldLabel.getText());
							_txtplaceholder.setText(_textFieldLabel.getText());
							field.setPlaceholder(_textFieldLabel.getText());
							_tree.repaint();
						}
					}
				}
			}
		});
		_textFieldLabel.setText("Label");
		_textFieldLabel.setColumns(10);
		
		JLabel lblLabel = new JLabel("Label");
		
		JLabel lblType_1 = new JLabel("Type");
		
		_textFieldComment = new JTextField();
		_textFieldComment.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent arg0) {
				if (_textFieldComment.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.FIELD.equals(nodeData.getClass().getSimpleName())) {
							((Field) nodeData).setComment(_textFieldComment.getText());
							_tree.repaint();
						}
					}
				}
			}
		});
		_textFieldComment.setText("Label");
		_textFieldComment.setColumns(10);
		
		JButton btnAdd = new JButton("Add");
		btnAdd.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				DefaultTableModel tableModel = (DefaultTableModel) _tableValueList.getModel();
				tableModel.addRow(new Object[]{"", ""});
			}
		});
		
		btnDelete = new JButton("Delete");
		btnDelete.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				int row = _tableValueList.getSelectedRow();
				if(-1 != row){
					DefaultTableModel tableModel = (DefaultTableModel) _tableValueList.getModel();
					tableModel.removeRow(row);
				}
			}
		});
		
		btnSave_1 = new JButton("Save");
		btnSave_1.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (null != _currentNode) {
					Object nodeData = _currentNode.getUserObject();
					if (null != nodeData && MetaData.FIELD.equals(nodeData.getClass().getSimpleName())) {
						logger.debug("...........");
						List<Option> options = new ArrayList<Option>();
						DefaultTableModel tableModel = (DefaultTableModel) _tableValueList.getModel();
						int rowCount=tableModel.getRowCount();
						for(int i = 0; i < rowCount; i++){
							Option o = new Option();
						    o.setValue((String)tableModel.getValueAt(i, 0));
						    o.setLabel((String)tableModel.getValueAt(i, 1));
						    logger.debug(tableModel.getValueAt(i, 1));
						    options.add(o);
						}
						((Field)nodeData).setOptions(options);
					}
				}
			}
		});
		
		JScrollPane scrollPane_1 = new JScrollPane();
		
		_tableValueList = new JTable(new DefaultTableModel(
			new Object[][] {
			},
			new String[] {
				"Value", "Label"
			}
		) {
			Class[] columnTypes = new Class[] {
				Object.class, String.class
			};
			@Override
			public Class getColumnClass(int columnIndex) {
				return columnTypes[columnIndex];
			}
		});
		scrollPane_1.setViewportView(_tableValueList);
		//_tableValueList.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		_tableValueList.putClientProperty("terminateEditOnFocusLost", true);
		_tableValueList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		
		_txtplaceholder = new JTextField();
		_txtplaceholder.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent arg0) {
				if (_txtplaceholder.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.FIELD.equals(nodeData.getClass().getSimpleName())) {
							((Field) nodeData).setPlaceholder(_txtplaceholder.getText());
							_tree.repaint();
						}
					}
				}
			}
		});
		_txtplaceholder.setText("_placeholder");
		_txtplaceholder.setColumns(10);
		
		JLabel lblPlaceholder = new JLabel("Placeholder");
		
		JLabel lblUnit = new JLabel("Unit");
		
		_txtunit = new JTextField();
		_txtunit.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent e) {
				if (_txtunit.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.FIELD.equals(nodeData.getClass().getSimpleName())) {
							((Field) nodeData).setUnit(_txtunit.getText());
							_tree.repaint();
						}
					}
				}
			}
		});
		_txtunit.setText("_unit");
		_txtunit.setColumns(10);
		
		JLabel lblDefault = new JLabel("Default");
		
		_txtdefault = new JTextField();
		_txtdefault.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent arg0) {
				if (_txtdefault.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.FIELD.equals(nodeData.getClass().getSimpleName())) {
							((Field) nodeData).setDef(_txtdefault.getText());
							_tree.repaint();
						}
					}
				}
			}
		});
		_txtdefault.setText("_default");
		_txtdefault.setColumns(10);
		
		_textFieldRemoteURL = new JTextField();
		_textFieldRemoteURL.addCaretListener(new CaretListener() {
			@Override
			public void caretUpdate(CaretEvent arg0) {
				if (_textFieldRemoteURL.isFocusOwner()) {
					if (null != _currentNode) {
						Object nodeData = _currentNode.getUserObject();
						if (null != nodeData && MetaData.FIELD.equals(nodeData.getClass().getSimpleName())) {
							((Field) nodeData).setRemoteURL(_textFieldRemoteURL.getText());
							_tree.repaint();
						}
					}
				}
			}
		});
		_textFieldRemoteURL.setToolTipText("Remote URL");
		_textFieldRemoteURL.setColumns(10);
		
		JLabel lblRemoteUrlFor = new JLabel("Remote URL for combox:");
		
		JLabel lblMapType = new JLabel("Map Type:");
		
		JLabel lblMapClass = new JLabel("Map Class:");
		
		_comboBox_MapType = new JComboBox();
		_comboBox_MapType.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if (null != _currentNode) {
					Object nodeData = _currentNode.getUserObject();
					if (null != nodeData && MetaData.FIELD.equals(nodeData.getClass().getSimpleName())) {
						((Field) nodeData).setMap_type(_comboBox_MapType.getSelectedIndex());
					}
				}
			}
		});
		_comboBox_MapType.setModel(new DefaultComboBoxModel(new String[] {"0", "1:1", "1:N"}));
		
		_textField_Map_Class = new JTextField();
		_textField_Map_Class.addCaretListener(new CaretListener() {
			public void caretUpdate(CaretEvent arg0) {
				if (null != _currentNode) {
					Object nodeData = _currentNode.getUserObject();
					if (null != nodeData && MetaData.FIELD.equals(nodeData.getClass().getSimpleName())) {
						((Field) nodeData).setMap_class(_textField_Map_Class.getText());
					}
				}
			}
		});
		_textField_Map_Class.setColumns(10);
		GroupLayout gl__panelField = new GroupLayout(_panelField);
		gl__panelField.setHorizontalGroup(
			gl__panelField.createParallelGroup(Alignment.LEADING)
				.addGroup(gl__panelField.createSequentialGroup()
					.addGroup(gl__panelField.createParallelGroup(Alignment.LEADING)
						.addGroup(Alignment.TRAILING, gl__panelField.createParallelGroup(Alignment.TRAILING)
							.addGroup(Alignment.LEADING, gl__panelField.createSequentialGroup()
								.addContainerGap()
								.addComponent(scrollPane_1, GroupLayout.DEFAULT_SIZE, 836, Short.MAX_VALUE))
							.addGroup(gl__panelField.createSequentialGroup()
								.addGap(12)
								.addGroup(gl__panelField.createParallelGroup(Alignment.LEADING)
									.addGroup(gl__panelField.createSequentialGroup()
										.addComponent(lblName_3, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
										.addGap(19)
										.addComponent(_textFiledFieldName, GroupLayout.DEFAULT_SIZE, 764, Short.MAX_VALUE))
									.addGroup(gl__panelField.createSequentialGroup()
										.addComponent(lblLabel, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
										.addGap(19)
										.addComponent(_textFieldLabel, GroupLayout.DEFAULT_SIZE, 764, Short.MAX_VALUE))
									.addGroup(gl__panelField.createSequentialGroup()
										.addComponent(lblType_3)
										.addGap(19)
										.addComponent(_textFieldComment, GroupLayout.DEFAULT_SIZE, 763, Short.MAX_VALUE))
									.addGroup(gl__panelField.createSequentialGroup()
										.addComponent(lblPlaceholder, GroupLayout.PREFERRED_SIZE, 72, GroupLayout.PREFERRED_SIZE)
										.addGap(2)
										.addComponent(_txtplaceholder, GroupLayout.DEFAULT_SIZE, 764, Short.MAX_VALUE))
									.addGroup(gl__panelField.createSequentialGroup()
										.addComponent(lblUnit, GroupLayout.PREFERRED_SIZE, 72, GroupLayout.PREFERRED_SIZE)
										.addGap(2)
										.addComponent(_txtunit, GroupLayout.DEFAULT_SIZE, 764, Short.MAX_VALUE))
									.addGroup(gl__panelField.createSequentialGroup()
										.addGroup(gl__panelField.createParallelGroup(Alignment.LEADING)
											.addComponent(lblType_1, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
											.addComponent(lblDefault))
										.addGap(18)
										.addGroup(gl__panelField.createParallelGroup(Alignment.LEADING)
											.addComponent(_txtdefault, GroupLayout.DEFAULT_SIZE, 764, Short.MAX_VALUE)
											.addComponent(_comboBoxFieldType, 0, 764, Short.MAX_VALUE)))
									.addGroup(gl__panelField.createSequentialGroup()
										.addPreferredGap(ComponentPlacement.RELATED)
										.addComponent(lblRemoteUrlFor, GroupLayout.PREFERRED_SIZE, 186, GroupLayout.PREFERRED_SIZE)
										.addPreferredGap(ComponentPlacement.UNRELATED)
										.addComponent(_textFieldRemoteURL, GroupLayout.DEFAULT_SIZE, 636, Short.MAX_VALUE)))))
						.addGroup(gl__panelField.createSequentialGroup()
							.addContainerGap()
							.addComponent(btnAdd, GroupLayout.PREFERRED_SIZE, 140, GroupLayout.PREFERRED_SIZE)
							.addPreferredGap(ComponentPlacement.RELATED)
							.addComponent(btnDelete, GroupLayout.PREFERRED_SIZE, 134, GroupLayout.PREFERRED_SIZE)
							.addPreferredGap(ComponentPlacement.UNRELATED)
							.addComponent(btnSave_1, GroupLayout.PREFERRED_SIZE, 133, GroupLayout.PREFERRED_SIZE))
						.addGroup(gl__panelField.createSequentialGroup()
							.addContainerGap()
							.addComponent(lblMapType)
							.addGap(18)
							.addComponent(_comboBox_MapType, GroupLayout.PREFERRED_SIZE, 168, GroupLayout.PREFERRED_SIZE)
							.addPreferredGap(ComponentPlacement.UNRELATED)
							.addComponent(lblMapClass)
							.addPreferredGap(ComponentPlacement.UNRELATED)
							.addComponent(_textField_Map_Class, GroupLayout.PREFERRED_SIZE, 291, GroupLayout.PREFERRED_SIZE)))
					.addContainerGap())
		);
		gl__panelField.setVerticalGroup(
			gl__panelField.createParallelGroup(Alignment.LEADING)
				.addGroup(gl__panelField.createSequentialGroup()
					.addGroup(gl__panelField.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelField.createSequentialGroup()
							.addGap(12)
							.addComponent(lblName_3))
						.addGroup(gl__panelField.createSequentialGroup()
							.addGap(10)
							.addComponent(_textFiledFieldName, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)))
					.addGroup(gl__panelField.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelField.createSequentialGroup()
							.addGap(10)
							.addComponent(lblLabel))
						.addGroup(gl__panelField.createSequentialGroup()
							.addGap(8)
							.addComponent(_textFieldLabel, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)))
					.addGroup(gl__panelField.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelField.createSequentialGroup()
							.addGap(10)
							.addComponent(lblType_3))
						.addGroup(gl__panelField.createSequentialGroup()
							.addGap(8)
							.addComponent(_textFieldComment, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)))
					.addGroup(gl__panelField.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelField.createSequentialGroup()
							.addGap(12)
							.addComponent(lblPlaceholder, GroupLayout.PREFERRED_SIZE, 19, GroupLayout.PREFERRED_SIZE))
						.addGroup(gl__panelField.createSequentialGroup()
							.addPreferredGap(ComponentPlacement.RELATED)
							.addComponent(_txtplaceholder, GroupLayout.PREFERRED_SIZE, 25, GroupLayout.PREFERRED_SIZE)))
					.addGroup(gl__panelField.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelField.createSequentialGroup()
							.addGap(9)
							.addComponent(lblUnit, GroupLayout.PREFERRED_SIZE, 19, GroupLayout.PREFERRED_SIZE))
						.addGroup(gl__panelField.createSequentialGroup()
							.addPreferredGap(ComponentPlacement.RELATED)
							.addComponent(_txtunit, GroupLayout.PREFERRED_SIZE, 25, GroupLayout.PREFERRED_SIZE)))
					.addPreferredGap(ComponentPlacement.UNRELATED)
					.addGroup(gl__panelField.createParallelGroup(Alignment.BASELINE)
						.addComponent(lblDefault)
						.addComponent(_txtdefault, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
					.addGap(7)
					.addGroup(gl__panelField.createParallelGroup(Alignment.BASELINE)
						.addComponent(_comboBoxFieldType, GroupLayout.PREFERRED_SIZE, 27, GroupLayout.PREFERRED_SIZE)
						.addComponent(lblType_1))
					.addPreferredGap(ComponentPlacement.RELATED)
					.addGroup(gl__panelField.createParallelGroup(Alignment.TRAILING)
						.addComponent(_textFieldRemoteURL, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
						.addComponent(lblRemoteUrlFor))
					.addGap(18)
					.addGroup(gl__panelField.createParallelGroup(Alignment.BASELINE)
						.addComponent(lblMapType)
						.addComponent(_comboBox_MapType, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
						.addComponent(lblMapClass)
						.addComponent(_textField_Map_Class, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
					.addPreferredGap(ComponentPlacement.RELATED, 23, Short.MAX_VALUE)
					.addGroup(gl__panelField.createParallelGroup(Alignment.BASELINE)
						.addComponent(btnAdd, GroupLayout.PREFERRED_SIZE, 27, GroupLayout.PREFERRED_SIZE)
						.addComponent(btnDelete, GroupLayout.PREFERRED_SIZE, 27, GroupLayout.PREFERRED_SIZE)
						.addComponent(btnSave_1, GroupLayout.PREFERRED_SIZE, 27, GroupLayout.PREFERRED_SIZE))
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(scrollPane_1, GroupLayout.PREFERRED_SIZE, 158, GroupLayout.PREFERRED_SIZE)
					.addContainerGap())
		);
		_panelField.setLayout(gl__panelField);
		_tabbedPane.addTab("Field Constraint", null, _panelFieldConstraint, null);
		
		_comboBoxFieldConstraint = new JComboBox();
		_comboBoxFieldConstraint.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (null != _currentNode) {
					Object nodeData = _currentNode.getUserObject();
					if (null != nodeData && MetaData.FIELDCONSTRAINT.equals(nodeData.getClass().getSimpleName())) {
						((FieldConstraint) nodeData).setName(_comboBoxFieldConstraint.getSelectedItem().toString());
						logger.debug(e.getActionCommand());
						_tree.repaint();
					}
				}
			}
		});
		_comboBoxFieldConstraint.setModel(new DefaultComboBoxModel(new String[] {"not null", "unique", "primary key", "foreign key", "check", "default"}));
		_comboBoxFieldConstraint.setEditable(true);
		GroupLayout gl__panelFieldConstraint = new GroupLayout(_panelFieldConstraint);
		gl__panelFieldConstraint.setHorizontalGroup(
			gl__panelFieldConstraint.createParallelGroup(Alignment.LEADING)
				.addGroup(gl__panelFieldConstraint.createSequentialGroup()
					.addGap(12)
					.addComponent(lblConstraint, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
					.addGap(18)
					.addComponent(_comboBoxFieldConstraint, 0, 773, Short.MAX_VALUE)
					.addContainerGap())
		);
		gl__panelFieldConstraint.setVerticalGroup(
			gl__panelFieldConstraint.createParallelGroup(Alignment.LEADING)
				.addGroup(gl__panelFieldConstraint.createSequentialGroup()
					.addGroup(gl__panelFieldConstraint.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelFieldConstraint.createSequentialGroup()
							.addGap(12)
							.addComponent(lblConstraint))
						.addGroup(gl__panelFieldConstraint.createSequentialGroup()
							.addGap(8)
							.addComponent(_comboBoxFieldConstraint, GroupLayout.PREFERRED_SIZE, 27, GroupLayout.PREFERRED_SIZE)))
					.addContainerGap(486, Short.MAX_VALUE))
		);
		_panelFieldConstraint.setLayout(gl__panelFieldConstraint);
		_tabbedPane.addTab("Field Validator", null, _panelFieldValidator, null);
		GroupLayout gl__panelFieldValidator = new GroupLayout(_panelFieldValidator);
		gl__panelFieldValidator.setHorizontalGroup(
			gl__panelFieldValidator.createParallelGroup(Alignment.LEADING)
				.addGroup(gl__panelFieldValidator.createSequentialGroup()
					.addGap(12)
					.addGroup(gl__panelFieldValidator.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelFieldValidator.createSequentialGroup()
							.addComponent(lblType, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
							.addGap(18)
							.addComponent(_comboBoxFieldValidatorType, 0, 779, Short.MAX_VALUE))
						.addGroup(gl__panelFieldValidator.createSequentialGroup()
							.addComponent(lblMessage, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
							.addGap(18)
							.addComponent(_textFieldFieldValidatorMessage, GroupLayout.DEFAULT_SIZE, 773, Short.MAX_VALUE)
							.addContainerGap())))
		);
		gl__panelFieldValidator.setVerticalGroup(
			gl__panelFieldValidator.createParallelGroup(Alignment.LEADING)
				.addGroup(gl__panelFieldValidator.createSequentialGroup()
					.addGroup(gl__panelFieldValidator.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelFieldValidator.createSequentialGroup()
							.addGap(12)
							.addComponent(lblType))
						.addGroup(gl__panelFieldValidator.createSequentialGroup()
							.addGap(8)
							.addComponent(_comboBoxFieldValidatorType, GroupLayout.PREFERRED_SIZE, 27, GroupLayout.PREFERRED_SIZE)))
					.addGroup(gl__panelFieldValidator.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelFieldValidator.createSequentialGroup()
							.addGap(15)
							.addComponent(lblMessage))
						.addGroup(gl__panelFieldValidator.createSequentialGroup()
							.addGap(12)
							.addComponent(_textFieldFieldValidatorMessage, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE))))
		);
		_panelFieldValidator.setLayout(gl__panelFieldValidator);
		_tabbedPane.addTab("FieldValidatorParameter", null, _panelFieldValidatorParameter, null);
		GroupLayout gl__panelFieldValidatorParameter = new GroupLayout(_panelFieldValidatorParameter);
		gl__panelFieldValidatorParameter.setHorizontalGroup(
			gl__panelFieldValidatorParameter.createParallelGroup(Alignment.LEADING)
				.addGroup(gl__panelFieldValidatorParameter.createSequentialGroup()
					.addGap(12)
					.addGroup(gl__panelFieldValidatorParameter.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelFieldValidatorParameter.createSequentialGroup()
							.addComponent(lblName, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
							.addGap(18)
							.addComponent(_comboBoxFieldValidatorParamName, 0, 773, Short.MAX_VALUE))
						.addGroup(gl__panelFieldValidatorParameter.createSequentialGroup()
							.addComponent(lblValue, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
							.addGap(18)
							.addComponent(_textFieldFieldValidatorParamValue, GroupLayout.DEFAULT_SIZE, 773, Short.MAX_VALUE)))
					.addContainerGap())
		);
		gl__panelFieldValidatorParameter.setVerticalGroup(
			gl__panelFieldValidatorParameter.createParallelGroup(Alignment.LEADING)
				.addGroup(gl__panelFieldValidatorParameter.createSequentialGroup()
					.addGap(12)
					.addGroup(gl__panelFieldValidatorParameter.createParallelGroup(Alignment.LEADING)
						.addComponent(lblName)
						.addComponent(_comboBoxFieldValidatorParamName, GroupLayout.PREFERRED_SIZE, 27, GroupLayout.PREFERRED_SIZE))
					.addGroup(gl__panelFieldValidatorParameter.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelFieldValidatorParameter.createSequentialGroup()
							.addGap(8)
							.addComponent(lblValue))
						.addGroup(gl__panelFieldValidatorParameter.createSequentialGroup()
							.addPreferredGap(ComponentPlacement.RELATED)
							.addComponent(_textFieldFieldValidatorParamValue, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE))))
		);
		_panelFieldValidatorParameter.setLayout(gl__panelFieldValidatorParameter);
		_tabbedPane.addTab("TableConstraint", null, _panelTableConstraint, null);
		
		_comboBoxTableConstraint = new JComboBox();
		_comboBoxTableConstraint.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (null != _currentNode) {
					Object nodeData = _currentNode.getUserObject();
					if (null != nodeData && MetaData.TABLECONSTRAINT.equals(nodeData.getClass().getSimpleName())) {
						((TableConstraint) nodeData).setName(_comboBoxTableConstraint.getSelectedItem().toString());
						_tree.repaint();
					}
				}
			}
		});
		_comboBoxTableConstraint.setEditable(true);
		_comboBoxTableConstraint.setModel(new DefaultComboBoxModel(new String[] {"not null", "unique", "primary key", "foreign key", "check", "default"}));
		GroupLayout gl__panelTableConstraint = new GroupLayout(_panelTableConstraint);
		gl__panelTableConstraint.setHorizontalGroup(
			gl__panelTableConstraint.createParallelGroup(Alignment.LEADING)
				.addGroup(gl__panelTableConstraint.createSequentialGroup()
					.addGroup(gl__panelTableConstraint.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelTableConstraint.createSequentialGroup()
							.addGap(12)
							.addComponent(lblConstraint_1, GroupLayout.PREFERRED_SIZE, 75, GroupLayout.PREFERRED_SIZE))
						.addGroup(gl__panelTableConstraint.createSequentialGroup()
							.addGap(85)
							.addComponent(_comboBoxTableConstraint, 0, 773, Short.MAX_VALUE)))
					.addContainerGap())
		);
		gl__panelTableConstraint.setVerticalGroup(
			gl__panelTableConstraint.createParallelGroup(Alignment.LEADING)
				.addGroup(gl__panelTableConstraint.createSequentialGroup()
					.addGroup(gl__panelTableConstraint.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelTableConstraint.createSequentialGroup()
							.addGap(12)
							.addComponent(lblConstraint_1))
						.addGroup(gl__panelTableConstraint.createSequentialGroup()
							.addGap(8)
							.addComponent(_comboBoxTableConstraint, GroupLayout.PREFERRED_SIZE, 27, GroupLayout.PREFERRED_SIZE)))
					.addContainerGap(486, Short.MAX_VALUE))
		);
		_panelTableConstraint.setLayout(gl__panelTableConstraint);
		_tabbedPane.addTab("API", null, _panelAPI, null);
		GroupLayout gl__panelAPI = new GroupLayout(_panelAPI);
		gl__panelAPI.setHorizontalGroup(
			gl__panelAPI.createParallelGroup(Alignment.LEADING)
				.addGroup(gl__panelAPI.createSequentialGroup()
					.addGap(12)
					.addGroup(gl__panelAPI.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelAPI.createSequentialGroup()
							.addComponent(lblName_1, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
							.addGap(18)
							.addComponent(_textFieldApiName, GroupLayout.DEFAULT_SIZE, 773, Short.MAX_VALUE))
						.addGroup(gl__panelAPI.createSequentialGroup()
							.addComponent(lblReturn, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
							.addGap(18)
							.addComponent(_textFieldApiReturn, GroupLayout.DEFAULT_SIZE, 773, Short.MAX_VALUE))
						.addGroup(gl__panelAPI.createSequentialGroup()
							.addComponent(lblComment_1)
							.addGap(18)
							.addComponent(_dtrpnApiDoc, GroupLayout.DEFAULT_SIZE, 773, Short.MAX_VALUE)))
					.addContainerGap())
		);
		gl__panelAPI.setVerticalGroup(
			gl__panelAPI.createParallelGroup(Alignment.LEADING)
				.addGroup(gl__panelAPI.createSequentialGroup()
					.addGroup(gl__panelAPI.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelAPI.createSequentialGroup()
							.addGap(12)
							.addComponent(lblName_1))
						.addGroup(gl__panelAPI.createSequentialGroup()
							.addGap(10)
							.addComponent(_textFieldApiName, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)))
					.addGroup(gl__panelAPI.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelAPI.createSequentialGroup()
							.addGap(14)
							.addComponent(lblReturn))
						.addGroup(gl__panelAPI.createSequentialGroup()
							.addGap(12)
							.addComponent(_textFieldApiReturn, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)))
					.addGap(10)
					.addGroup(gl__panelAPI.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelAPI.createSequentialGroup()
							.addGap(2)
							.addComponent(_dtrpnApiDoc, GroupLayout.PREFERRED_SIZE, 131, GroupLayout.PREFERRED_SIZE))
						.addComponent(lblComment_1)))
		);
		_panelAPI.setLayout(gl__panelAPI);
		_tabbedPane.addTab("APIParam", null, _panelAPIParam, null);
		
		_comboBoxApiParamType = new JComboBox();
		_comboBoxApiParamType.setModel(new DefaultComboBoxModel(new String[] {"int", "String", "DateTime", "File"}));
		_comboBoxApiParamType.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (null != _currentNode) {
					Object nodeData = _currentNode.getUserObject();
					if (null != nodeData && MetaData.APIPARAM.equals(nodeData.getClass().getSimpleName())) {
						((APIParam) nodeData).setType(_comboBoxApiParamType.getSelectedItem().toString());
					}
				}
			}
		});
		_comboBoxApiParamType.setEditable(true);
		GroupLayout gl__panelAPIParam = new GroupLayout(_panelAPIParam);
		gl__panelAPIParam.setHorizontalGroup(
			gl__panelAPIParam.createParallelGroup(Alignment.LEADING)
				.addGroup(gl__panelAPIParam.createSequentialGroup()
					.addGap(12)
					.addGroup(gl__panelAPIParam.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelAPIParam.createSequentialGroup()
							.addComponent(lblName_2, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
							.addGap(1)
							.addComponent(_textFieldApiParamName, GroupLayout.DEFAULT_SIZE, 790, Short.MAX_VALUE))
						.addGroup(gl__panelAPIParam.createSequentialGroup()
							.addComponent(lblType_2, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
							.addGap(1)
							.addComponent(_comboBoxApiParamType, 0, 790, Short.MAX_VALUE)))
					.addContainerGap())
		);
		gl__panelAPIParam.setVerticalGroup(
			gl__panelAPIParam.createParallelGroup(Alignment.LEADING)
				.addGroup(gl__panelAPIParam.createSequentialGroup()
					.addGap(12)
					.addGroup(gl__panelAPIParam.createParallelGroup(Alignment.LEADING)
						.addComponent(lblName_2)
						.addComponent(_textFieldApiParamName, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE))
					.addGap(8)
					.addGroup(gl__panelAPIParam.createParallelGroup(Alignment.LEADING)
						.addComponent(lblType_2)
						.addComponent(_comboBoxApiParamType, GroupLayout.PREFERRED_SIZE, 27, GroupLayout.PREFERRED_SIZE)))
		);
		_panelAPIParam.setLayout(gl__panelAPIParam);
		_tabbedPane.addTab("APIParamValidator", null, _panelAPIParamValidator, null);
		GroupLayout gl__panelAPIParamValidator = new GroupLayout(_panelAPIParamValidator);
		gl__panelAPIParamValidator.setHorizontalGroup(
			gl__panelAPIParamValidator.createParallelGroup(Alignment.LEADING)
				.addGroup(gl__panelAPIParamValidator.createSequentialGroup()
					.addGap(12)
					.addGroup(gl__panelAPIParamValidator.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelAPIParamValidator.createSequentialGroup()
							.addComponent(label, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
							.addGap(18)
							.addComponent(_comboBoxAPIValidatorType, 0, 773, Short.MAX_VALUE))
						.addGroup(gl__panelAPIParamValidator.createSequentialGroup()
							.addComponent(label_1, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
							.addGap(18)
							.addComponent(_textFieldAPIParamValidatorMessage, GroupLayout.DEFAULT_SIZE, 773, Short.MAX_VALUE)))
					.addContainerGap())
		);
		gl__panelAPIParamValidator.setVerticalGroup(
			gl__panelAPIParamValidator.createParallelGroup(Alignment.LEADING)
				.addGroup(gl__panelAPIParamValidator.createSequentialGroup()
					.addGroup(gl__panelAPIParamValidator.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelAPIParamValidator.createSequentialGroup()
							.addGap(12)
							.addComponent(label))
						.addGroup(gl__panelAPIParamValidator.createSequentialGroup()
							.addGap(8)
							.addComponent(_comboBoxAPIValidatorType, GroupLayout.PREFERRED_SIZE, 27, GroupLayout.PREFERRED_SIZE)))
					.addGroup(gl__panelAPIParamValidator.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelAPIParamValidator.createSequentialGroup()
							.addGap(15)
							.addComponent(label_1))
						.addGroup(gl__panelAPIParamValidator.createSequentialGroup()
							.addGap(12)
							.addComponent(_textFieldAPIParamValidatorMessage, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE))))
		);
		_panelAPIParamValidator.setLayout(gl__panelAPIParamValidator);
		_tabbedPane.addTab("API Param Validator Param", null, _panelAPIParamValidatorParam, null);
		GroupLayout gl__panelAPIParamValidatorParam = new GroupLayout(_panelAPIParamValidatorParam);
		gl__panelAPIParamValidatorParam.setHorizontalGroup(
			gl__panelAPIParamValidatorParam.createParallelGroup(Alignment.LEADING)
				.addGroup(gl__panelAPIParamValidatorParam.createSequentialGroup()
					.addGap(12)
					.addGroup(gl__panelAPIParamValidatorParam.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelAPIParamValidatorParam.createSequentialGroup()
							.addComponent(label_2, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
							.addGap(18)
							.addComponent(_textFieldAPIParamValidatorParamName, GroupLayout.PREFERRED_SIZE, 773, GroupLayout.PREFERRED_SIZE))
						.addGroup(gl__panelAPIParamValidatorParam.createSequentialGroup()
							.addComponent(label_4, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
							.addGap(18)
							.addComponent(_comboBoxAPIParamValidatorParamType, 0, 773, Short.MAX_VALUE)
							.addContainerGap())
						.addGroup(gl__panelAPIParamValidatorParam.createSequentialGroup()
							.addComponent(label_3, GroupLayout.PREFERRED_SIZE, 55, GroupLayout.PREFERRED_SIZE)
							.addGap(18)
							.addComponent(_textFieldAPIParamValidatorParamValue, GroupLayout.DEFAULT_SIZE, 773, Short.MAX_VALUE)
							.addContainerGap())))
		);
		gl__panelAPIParamValidatorParam.setVerticalGroup(
			gl__panelAPIParamValidatorParam.createParallelGroup(Alignment.LEADING)
				.addGroup(gl__panelAPIParamValidatorParam.createSequentialGroup()
					.addGap(10)
					.addGroup(gl__panelAPIParamValidatorParam.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelAPIParamValidatorParam.createSequentialGroup()
							.addGap(2)
							.addComponent(label_2))
						.addComponent(_textFieldAPIParamValidatorParamName, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE))
					.addGap(12)
					.addGroup(gl__panelAPIParamValidatorParam.createParallelGroup(Alignment.LEADING)
						.addComponent(label_4)
						.addComponent(_comboBoxAPIParamValidatorParamType, GroupLayout.PREFERRED_SIZE, 27, GroupLayout.PREFERRED_SIZE))
					.addGroup(gl__panelAPIParamValidatorParam.createParallelGroup(Alignment.LEADING)
						.addGroup(gl__panelAPIParamValidatorParam.createSequentialGroup()
							.addGap(8)
							.addComponent(label_3))
						.addGroup(gl__panelAPIParamValidatorParam.createSequentialGroup()
							.addPreferredGap(ComponentPlacement.RELATED)
							.addComponent(_textFieldAPIParamValidatorParamValue, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE))))
		);
		_panelAPIParamValidatorParam.setLayout(gl__panelAPIParamValidatorParam);

		initPopupMenu();
		initEditors();
		
	}

	private void onOpen(){
		JFileChooser fileChooser = new JFileChooser();
		FileNameExtensionFilter filter = new FileNameExtensionFilter("Meta data file", "tdd");
		fileChooser.setFileFilter(filter);
		fileChooser.setCurrentDirectory(new File("."));
		int returnValue = fileChooser.showOpenDialog(_frame);

		if (returnValue == JFileChooser.APPROVE_OPTION) {
			File file = fileChooser.getSelectedFile();
			try {
				String json = "";
				BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "utf-8"));
				String str;
				while((str = bufferedReader.readLine()) != null){
					json += str;
				}
				bufferedReader.close();
				logger.debug(json);
	    		Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
	    		
	    		MetaData metaData = gson.fromJson(json, MetaData.class);
	    		/*
	    		 * Why??????????????
	    		 */
	    		//MetaData metaData = gson.fromJson(bufferReader, MetaData.class);
	    		logger.debug(metaData.getTables().size());
	    		MetaDataTreeHelper.fillTree(_tree, metaData);
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}	
		selectView(MetaData.CONSOLE);
	}
	
	private boolean selectView(String viewName){
		Object editor = null;
		logger.debug(viewName);
		if(_editors.containsKey(viewName)){
			editor = _editors.get(viewName);
			
		}else{
			editor = _editors.get(MetaData.CONSOLE);
		}
		if(null != editor){
			if(editor.getClass().getSimpleName().equals("JScrollPane")){
				_tabbedPane.setSelectedComponent((JScrollPane)editor);
			}else{
				_tabbedPane.setSelectedComponent((JPanel)editor);
			}
		}
		return true;
	}
	private void onGenerate(){
		logger.debug("Generating...");
		//String str = Main.class.getResource("/").getPath();
		File currentDir = new File("build.bat");
		
		logger.debug(currentDir.getAbsolutePath());
		JScrollPane editor  = (JScrollPane)_editors.get(MetaData.CONSOLE);
		if(null != editor){
    		MetaData metaData = MetaDataTreeHelper.retrieveTreeData(_tree);
    		String templateRoot = metaData.getSourceRoot();
    		String outputRoot = metaData.getOutputRoot();
    		String model = metaData.getModel();
    		
    		String tip = "source:    " + templateRoot + "\n";
    		tip += "output:    " + outputRoot + "\n";
    		tip += "model:    " + model + "\n";
    		int ret = JOptionPane.showConfirmDialog(null, tip, "提示:", JOptionPane.YES_NO_OPTION);
    		if(ret == JOptionPane.OK_OPTION){
				logger.debug(_outputRoot.getText());
				String encoding = metaData.getEncoding() != null ? metaData.getEncoding() : "UTF-8";
				//encoding = "utf-8";
				String message = Util.fmpp(templateRoot, outputRoot, model, encoding);
				logger.info(message);
				//_textAreaConsole.setText(res);
				_tabbedPane.setSelectedComponent(editor);
				
				//FileTransfer.encoding(outputRoot, "UTF-8", encoding);
/*				// Generate source document.
				logger.info("Begin to generate source document...");
				boolean res = JRHelper.exportSource2Docx(metaData.getArtifactid(), templateRoot, outputRoot, outputRoot);
				logger.info("Source document generated " + (res ? "succeed!" : "failed!"));
				//_textAreaConsole.setText("Source document generated!");
				// Generate data model document.
				logger.info("Begin to generate data model document...");
				JRHelper.exportMD2Docx(templateRoot, outputRoot, metaData);
				logger.info("Data model document generated " + (res ? "succeed!" : "failed!"));
				//_textAreaConsole.setText("Data model document generated " + (res ? "succeed!" : "failed!"));
*/
    		}else{
    			System.out.println("没打印");
    		}
    		
    		// Generate JXLS template
    		String groupid = metaData.getGroupid().replace(".", "/");
    		String artifactid = metaData.getArtifactid().replace(".", "/");

    		for(Table table : metaData.getTables()){
    			String moduleid = table.getModuleid().replace(".", "/");
    			String out = metaData.getOutputRoot() + "/main/java/" + groupid + "/" + artifactid + "/" + moduleid + "/domain/" + table.getName() + "-jxls-template.xls";
    			//Map beans = new HashMap();
				//beans.put("fields", table.getFields());
				
				push(table.getFields(), "/jxls_106.xls", out);
    		}
		}
		logger.debug("Code generation finished!");
		selectView(MetaData.CONSOLE);
	}
	
	private void push(List<Field> items, String template, String out){
	    try{
	    	List<Field> out_items = new ArrayList<Field>();
	    	InputStream is = Main.class.getResourceAsStream(template);
	        OutputStream os = new FileOutputStream(out);
            Context context = new Context();
            for(int i = 0; items != null && i < items.size(); i++){
            	Field field = (Field)items.get(i).deepClone();
            	field.setName("${objs." + field.getName() + "}");
            	out_items.add(field);
            }
            context.putVar("fields", out_items);
            if(null != is){
            	JxlsHelper.getInstance().processTemplate(is, os, context);
            	logger.info("- Executing:" + out);
            }else{
            	logger.error("Template is empty!");
            }
	    }catch(Exception e){
	    	logger.error(e.getMessage());
	    }
	}
	
	private void onSave(){
		JFileChooser fileChooser = new JFileChooser();
		FileNameExtensionFilter filter = new FileNameExtensionFilter("Meta data file", "tdd");
		fileChooser.setFileFilter(filter);
		fileChooser.setDialogType(JFileChooser.SAVE_DIALOG);
		fileChooser.setCurrentDirectory(new File("."));
		int returnValue = fileChooser.showSaveDialog(_frame);

		if (returnValue == JFileChooser.APPROVE_OPTION) {
			File file = fileChooser.getSelectedFile();
			if(!file.getName().endsWith(".tdd")){
				logger.debug(file.getAbsoluteFile());
				file = new File(file.getAbsoluteFile() + ".tdd");
			}
			try {
	    		Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().disableHtmlEscaping().create();
	    		MetaData metaData = MetaDataTreeHelper.retrieveTreeData(_tree);
	    		String json = gson.toJson(metaData);
				//String encoding = metaData.getEncoding();
				logger.info(json);
				BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf-8"));
	    		//String jsonTarget = new String(json.getBytes(), encoding); 
	    		//logger.info(jsonTarget);
	    		//String strGBK = URLEncoder.encode(json, encoding); 
	    		bufferedWriter.write(json);
	    		bufferedWriter.flush();
	    		bufferedWriter.close();
	    		
	    		logger.debug(metaData.getTables().size());
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}		
		selectView(MetaData.CONSOLE);
	}
	
	private void fillControlFromUserData(Object userData){
		if(null != userData){
			String type = userData.getClass().getSimpleName();
			if(MetaData.METADATA.equals(type)){
				MetaData o = (MetaData)userData;
				 _textFieldGroupid.setText(o.getGroupid());
				 _textFieldArtifactid.setText(o.getArtifactid());
				 this._txtArtifacten.setText(o.getArtifactid_en());
				 this._txtAbbr.setText(o.getArtifactid_en_abbr());
				 _textFieldCopyright.setText(o.getCopyright());
				 _textFieldAuthor.setText(o.getAuthor());
				 _txtEnocding.setText(o.getEncoding());
				 _textFieldVersion.setText(o.getVersion());
				 _sourceRoot.setText(o.getSourceRoot());
				 _outputRoot.setText(o.getOutputRoot());
				 _model.setText(o.getModel());
				 this._textFieldTableSpace.setText(o.getTableSpace());
				 this._textFieldTablePrefix.setText(o.getTablePrefix());
				 _comboBoxDatabase.setSelectedItem(o.getDatabase());
				 _textFieldDate.setText(o.getDate());
			}else if(MetaData.TABLE.equals(type)){
				Table o = (Table)userData;
				 _textFieldTableName.setText(o.getName());
				 _textFieldModuleid.setText(o.getModuleid());
				 _textFieldTableComment.setText(o.getComment());
				 _textFieldIDFieldName.setText(o.getIdFieldName());
				 _comboBoxTableTheme.setSelectedItem(o.getTheme());
				
			}else if(MetaData.FIELD.equals(type)){
				Field o = (Field)userData;
				_textFiledFieldName.setText(o.getName());
				_comboBoxFieldType.setSelectedItem(o.getType());
				_textFieldComment.setText(o.getComment());
				_textFieldLabel.setText(o.getLabel());
				this._txtplaceholder.setText(o.getPlaceholder());
				this._txtunit.setText(o.getUnit());
				this._txtdefault.setText(o.getDef());
				this._textFieldRemoteURL.setText(o.getRemoteURL());
				this._comboBox_MapType.setSelectedIndex(o.getMap_type());
				this._textField_Map_Class.setText(o.getMap_class());
				
				DefaultTableModel tableModel = (DefaultTableModel) _tableValueList.getModel();
				tableModel.setRowCount(0);
				List<Option> options = o.getOptions();
				if(null != options){
					for(Option option : options){
					    Object[] arr = new Object[2];
					    arr[0] = option.getValue();
					    arr[1] = option.getLabel();
					    tableModel.addRow(arr);
					}
				}
			}else if(MetaData.FIELDCONSTRAINT.equals(type)){
				FieldConstraint o = (FieldConstraint)userData;
				this._comboBoxFieldConstraint.setSelectedItem(o.getName());
				logger.debug("dddddddddddddddddddd");
			}else if(MetaData.FIELDVALIDATOR.equals(type)){
				FieldValidator o = (FieldValidator)userData;
				_comboBoxFieldValidatorType.setSelectedItem(o.getType());;
				logger.debug(o.getType());
				logger.debug(o.getMessage());
				_textFieldFieldValidatorMessage.setText(o.getMessage());;
				
			}else if(MetaData.FIELDVALIDATORPARAM.equals(type)){
				FieldValidatorParam o = (FieldValidatorParam)userData;
				_comboBoxFieldValidatorParamName.setSelectedItem(o.getName());
				_textFieldFieldValidatorParamValue.setText(o.getValue());
				_comboBoxFieldValidatorParamName.setSelectedItem(o.getName());
			}else if(MetaData.TABLECONSTRAINT.equals(type)){
				TableConstraint o = (TableConstraint)userData;
				_comboBoxTableConstraint.setSelectedItem(o.getName());
			}else if(MetaData.API.equals(type)){
				API o = (API)userData;
				_textFieldApiName.setText(o.getName());
				_textFieldApiReturn.setText(o.getReturn());;
				_dtrpnApiDoc.setText(o.getDoc());;
			}else if(MetaData.APIPARAM.equals(type)){
				APIParam o = (APIParam)userData;
				_textFieldApiParamName.setText(o.getName());
				_comboBoxApiParamType.setSelectedItem(o.getType());
			}else if(MetaData.APIVALIDATOR.equals(type)){
				APIValidator o = (APIValidator)userData;
				_comboBoxAPIValidatorType.setSelectedItem(o.getType());
				_textFieldAPIParamValidatorMessage.setText(o.getMessage());
	
			}else if(MetaData.APIVALIDATORPARAM.equals(type)){
				APIValidatorParam o = (APIValidatorParam)userData;
				_textFieldAPIParamValidatorParamName.setText(o.getName());;
				_textFieldAPIParamValidatorParamValue.setText(o.getValue());
				_comboBoxAPIParamValidatorParamType.setSelectedItem(o.getType());
	
			}
		}
	}

	private void initPopupMenu(){
		initMenu4MetaData();
		initMenu4Tables();
		initMenu4Table();
		
		initMenu4Fields();
		initMenu4Field();
		initMenu4FieldConstraints();
		initMenu4FieldConstraint();
		initMenu4FieldValidators();
		initMenu4FieldValidator();
		initMenu4FieldValidatorParams();
		initMenu4FieldValidatorParam();
		initMenu4TableConstraints();
		initMenu4TableConstraint();
		
		initMenu4APIS();
		initMenu4API();
		initMenu4APIParams();
		initMenu4APIParam();
		initMenu4APIValidators();
		initMenu4APIValidator();
		initMenu4APIValidatorParams();
		initMenu4APIValidatorParam();
		
		_popupMenus = new HashMap<String, JPopupMenu>();
		_popupMenus.put(MetaData.METADATA, this._menu4MetaData);
		_popupMenus.put(MetaData.TABLE, this._menu4Table);
		_popupMenus.put(MetaData.TABLES, this._menu4Tables);
		_popupMenus.put(MetaData.TABLECONSTRAINT, this._menu4TableConstraint);
		_popupMenus.put(MetaData.TABLECONSTRAINTS, this._menu4TableConstraints);

		_popupMenus.put(MetaData.API, this._menu4API);
		_popupMenus.put(MetaData.APIS, this._menu4APIS);
		_popupMenus.put(MetaData.APIPARAM, this._menu4APIParam);
		_popupMenus.put(MetaData.APIPARAMS, this._menu4APIParams);
		_popupMenus.put(MetaData.APIVALIDATOR, this._menu4APIValidator);
		_popupMenus.put(MetaData.APIVALIDATORS, this._menu4APIValidators);
		_popupMenus.put(MetaData.APIVALIDATORPARAM, this._menu4APIValidatorParam);
		_popupMenus.put(MetaData.APIVALIDATORPARAMS, this._menu4APIValidatorParams);

		_popupMenus.put(MetaData.FIELD, this._menu4Field);
		_popupMenus.put(MetaData.FIELDS, this._menu4Fields);
		_popupMenus.put(MetaData.FIELDCONSTRAINT, this._menu4FieldConstraint);
		_popupMenus.put(MetaData.FIELDCONSTRAINTS, this._menu4FieldConstraints);
		_popupMenus.put(MetaData.FIELDVALIDATOR, this._menu4FieldValidator);
		_popupMenus.put(MetaData.FIELDVALIDATORS, this._menu4FieldValidators);
		_popupMenus.put(MetaData.FIELDVALIDATORPARAM, this._menu4FieldValidatorParam);
		_popupMenus.put(MetaData.FIELDVALIDATORPARAMS, this._menu4FieldValidatorParams);
		
	}
	
	private void initEditors(){
		_editors = new HashMap<String, Object>();
		_editors.put(MetaData.CONSOLE, this._panelConsole);
		_editors.put(MetaData.METADATA, this._panelMetaData);
		_editors.put(MetaData.TABLE, this._panelTable);
		_editors.put(MetaData.TABLECONSTRAINT, this._panelTableConstraint);

		_editors.put(MetaData.API, this._panelAPI);
		_editors.put(MetaData.APIPARAM, this._panelAPIParam);
		_editors.put(MetaData.APIVALIDATOR, this._panelAPIParamValidator);
		_editors.put(MetaData.APIVALIDATORPARAM, this._panelAPIParamValidatorParam);

		_editors.put(MetaData.FIELD, this._panelField);
		_editors.put(MetaData.FIELDCONSTRAINT, this._panelFieldConstraint);
		_editors.put(MetaData.FIELDVALIDATOR, this._panelFieldValidator);
		_editors.put(MetaData.FIELDVALIDATORPARAM, this._panelFieldValidatorParameter);
	}
	private void initMenu4MetaData(){
		//Initialize menu for meta data.
		_menu4MetaData = new JPopupMenu();
		
		JMenuItem mntmNew = new JMenuItem("New Metadata");
		mntmNew.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				
				logger.debug("New Metadata - clicked!");
			}
		});
		_menu4MetaData.add(mntmNew);		
	}
	
	private void initMenu4Tables(){
		_menu4Tables = new JPopupMenu();
		
		JMenuItem mntmNew = new JMenuItem("New Table");
		mntmNew.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				String tableName = JOptionPane.showInputDialog("请输入表名称！");
				if (tableName.length() > 0) {
					addNewTable(tableName);
				}
			}
		});
		_menu4Tables.add(mntmNew);				
	}
	
	private void addNewTable(String tableName){
		DefaultMutableTreeNode tablesNode = (DefaultMutableTreeNode) _tree.getLastSelectedPathComponent();
		Table table = new Table(tableName);
		table.setName(table.getName());
		DefaultMutableTreeNode tableNode = new DefaultMutableTreeNode(table);
		// tableNode.setUserObject(table);
		tablesNode.add(tableNode);
		TreeNode[] nodes = tableNode.getPath();
		TreePath path = new TreePath(nodes);
		_tree.scrollPathToVisible(path);
		_tree.updateUI();
		MetaDataTreeHelper.insertTable(tableNode, table);
	}
	
	private void initMenu4Table(){
		_menu4Table = new JPopupMenu();
		
		JMenuItem mntmDelete = new JMenuItem("Delete Table");
		mntmDelete.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				removeCurrentNode();
				logger.debug("Delete Table - clicked!");
			}
		});
		JMenuItem mntmDuplicate = new JMenuItem("Duplicate Table");
		mntmDuplicate.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				logger.debug("Duplicate Table - clicked!");
				duplicateCurrentNode();
			}
		});
		_menu4Table.add(mntmDelete);						
		_menu4Table.add(mntmDuplicate);						
	}
	
	private void initMenu4Fields(){
		_menu4Fields = new JPopupMenu();
		
		JMenuItem mntmNew = new JMenuItem("New Field");
		mntmNew.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				DefaultMutableTreeNode feildsNode =  (DefaultMutableTreeNode)_tree.getLastSelectedPathComponent();
				Field field = new Field();
				field.setName(field.getName());
				DefaultMutableTreeNode fieldNode = new DefaultMutableTreeNode(field);
				//tableNode.setUserObject(table);
				feildsNode.add(fieldNode);
				TreeNode[] nodes = fieldNode.getPath();  
                TreePath path = new TreePath(nodes);  
                _tree.scrollPathToVisible(path);  
				_tree.updateUI();
				MetaDataTreeHelper.insertField(fieldNode, field);
			}
		});
		JMenuItem mntmNew4File = new JMenuItem("Parse Fields From File");
		mntmNew4File.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				JFileChooser fileChooser = new JFileChooser();
				fileChooser.setCurrentDirectory(new File("."));
				int returnValue = fileChooser.showOpenDialog(_frame);

				if (returnValue == JFileChooser.APPROVE_OPTION) {
					File file = fileChooser.getSelectedFile();
					if(null != file){
						DefaultMutableTreeNode feildsNode =  (DefaultMutableTreeNode)_tree.getLastSelectedPathComponent();
						FieldParser fp = new FieldParserImpl();
						logger.debug(file.getAbsolutePath());
						List<Field> fields = fp.load(file.getAbsolutePath());
						for(Field field : fields){
							DefaultMutableTreeNode fieldNode = new DefaultMutableTreeNode(field);
							feildsNode.add(fieldNode);
							MetaDataTreeHelper.insertField(fieldNode, field);
						}
						_tree.updateUI();
					}
				}
			}
		});
		_menu4Fields.add(mntmNew);								
		_menu4Fields.add(mntmNew4File);								
	}
	

	private void initMenu4Field(){
		_menu4Field = new JPopupMenu();
		
		JMenuItem mntmDelete = new JMenuItem("Delete Field");
		mntmDelete.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				removeCurrentNode();
				logger.debug("Delete Field - clicked!");
			}
		});
		JMenuItem mntmPrev = new JMenuItem("Add Prev Sibling");
		mntmPrev.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				addPrev();
				logger.debug("Add Prev Sibling - clicked!");
			}
		});
		JMenuItem mntmNext = new JMenuItem("Add Next Sibling");
		mntmNext.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				addNext();
				logger.debug("Add Next Sibling - clicked!");
			}
		});
		_menu4Field.add(mntmPrev);									
		_menu4Field.add(mntmNext);									
		_menu4Field.add(mntmDelete);									
	}

	private void initMenu4FieldConstraints(){
		_menu4FieldConstraints = new JPopupMenu();
		
		JMenuItem mntmNew = new JMenuItem("New Constraint");
		mntmNew.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				DefaultMutableTreeNode fieldConstraintsNode =  (DefaultMutableTreeNode)_tree.getLastSelectedPathComponent();
				FieldConstraint constraint = new FieldConstraint();
				constraint.setName("not null");
				DefaultMutableTreeNode constraintNode = new DefaultMutableTreeNode(constraint);
				//tableNode.setUserObject(table);
				fieldConstraintsNode.add(constraintNode);
				TreeNode[] nodes = constraintNode.getPath();  
                TreePath path = new TreePath(nodes);  
                _tree.scrollPathToVisible(path);  
				_tree.updateUI();
			}
		});
		_menu4FieldConstraints.add(mntmNew);										
	}
	

	private void removeCurrentNode(){
		DefaultMutableTreeNode currentNode =  (DefaultMutableTreeNode)_tree.getLastSelectedPathComponent();
		currentNode.removeFromParent(); 
		_tree.updateUI();
	}

	private void addPrev(){
		DefaultMutableTreeNode feildNode =  (DefaultMutableTreeNode)_tree.getLastSelectedPathComponent();
		DefaultMutableTreeNode feildsNode = (DefaultMutableTreeNode) feildNode.getParent();
		Field field = new Field();
		field.setName(field.getName());
		DefaultMutableTreeNode siblingNode = new DefaultMutableTreeNode(field);
		//tableNode.setUserObject(table);
		int index = feildsNode.getIndex(feildNode);
		feildsNode.insert(siblingNode, index);
		logger.debug(index);
		///feildNode.add(fieldNode);
		//TreeNode[] nodes = fieldNode.getPath();  
        //TreePath path = new TreePath(nodes);  
       // _tree.scrollPathToVisible(path);  
		MetaDataTreeHelper.insertField(siblingNode, field);
		_tree.updateUI();
	}
	
	private void addNext(){
		DefaultMutableTreeNode feildNode =  (DefaultMutableTreeNode)_tree.getLastSelectedPathComponent();
		DefaultMutableTreeNode feildsNode = (DefaultMutableTreeNode) feildNode.getParent();
		Field field = new Field();
		field.setName(field.getName());
		DefaultMutableTreeNode siblingNode = new DefaultMutableTreeNode(field);
		//tableNode.setUserObject(table);
		int index = feildsNode.getIndex(feildNode);
		feildsNode.insert(siblingNode, index + 1);
		logger.debug(index);
		///feildNode.add(fieldNode);
		//TreeNode[] nodes = fieldNode.getPath();  
        //TreePath path = new TreePath(nodes);  
       // _tree.scrollPathToVisible(path);  
		MetaDataTreeHelper.insertField(siblingNode, field);
		_tree.updateUI();
	}
	
	private void duplicateCurrentNode(){
		DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode) _tree.getLastSelectedPathComponent();
		DefaultMutableTreeNode tablesNode = (DefaultMutableTreeNode)currentNode.getParent();
		Table table = MetaDataTreeHelper.retrieveTableData(currentNode);
		DefaultMutableTreeNode tableNode = new DefaultMutableTreeNode(table);
		// tableNode.setUserObject(table);
		logger.debug(tableNode.getUserObject());
		tablesNode.add(tableNode);
		TreeNode[] nodes = tableNode.getPath();
		TreePath path = new TreePath(nodes);
		_tree.scrollPathToVisible(path);
		_tree.updateUI();
		MetaDataTreeHelper.insertTable(tableNode, table);
	}

	private void initMenu4FieldConstraint(){
		_menu4FieldConstraint = new JPopupMenu();
		
		JMenuItem mntmDelete = new JMenuItem("Delete Constraint");
		mntmDelete.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				removeCurrentNode();
				logger.debug("Delete Constraint - clicked!");
			}
		});
		_menu4FieldConstraint.add(mntmDelete);										
	}
	

	private void initMenu4FieldValidators(){
		_menu4FieldValidators = new JPopupMenu();
		
		JMenuItem mntmNew = new JMenuItem("New Field Validator");
		mntmNew.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				DefaultMutableTreeNode feildValidatorsNode =  (DefaultMutableTreeNode)_tree.getLastSelectedPathComponent();
				FieldValidator fieldValidator = new FieldValidator();
				fieldValidator.setType(fieldValidator.getType());
				DefaultMutableTreeNode fieldValidatorNode = new DefaultMutableTreeNode(fieldValidator);
				//tableNode.setUserObject(table);
				feildValidatorsNode.add(fieldValidatorNode);
				TreeNode[] nodes = fieldValidatorNode.getPath();  
                TreePath path = new TreePath(nodes);  
                _tree.scrollPathToVisible(path);  
				_tree.updateUI();
				MetaDataTreeHelper.insertFieldValidator(fieldValidatorNode, fieldValidator);
			}
		});
		_menu4FieldValidators.add(mntmNew);										
	}
	

	private void initMenu4FieldValidator(){
		_menu4FieldValidator = new JPopupMenu();
		
		JMenuItem mntmDelete = new JMenuItem("Delete Validator");
		mntmDelete.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				removeCurrentNode();
				logger.debug("Delete Validator - clicked!");
			}
		});
		_menu4FieldValidator.add(mntmDelete);										
	}
	

	private void initMenu4FieldValidatorParams(){
		_menu4FieldValidatorParams = new JPopupMenu();
		
		JMenuItem mntmNew = new JMenuItem("New Field Validator Params");
		mntmNew.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				DefaultMutableTreeNode fieldValidatorParamsNode =  (DefaultMutableTreeNode)_tree.getLastSelectedPathComponent();
				FieldValidatorParam fieldValidatorParam = new FieldValidatorParam();
				fieldValidatorParam.setName(fieldValidatorParam.getName());
				DefaultMutableTreeNode fieldValidatorParamNode = new DefaultMutableTreeNode(fieldValidatorParam);
				//tableNode.setUserObject(table);
				fieldValidatorParamsNode.add(fieldValidatorParamNode);
				TreeNode[] nodes = fieldValidatorParamNode.getPath();  
                TreePath path = new TreePath(nodes);  
                _tree.scrollPathToVisible(path);  
				_tree.updateUI();
				MetaDataTreeHelper.insertFieldValidatorParam(fieldValidatorParamNode, fieldValidatorParam);
			}
		});
		_menu4FieldValidatorParams.add(mntmNew);										
	}
	

	private void initMenu4FieldValidatorParam(){
		_menu4FieldValidatorParam = new JPopupMenu();
		
		JMenuItem mntmDelete = new JMenuItem("Delete Validator Param");
		mntmDelete.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				removeCurrentNode();
				logger.debug("Delete Validator Param - clicked!");
			}
		});
		_menu4FieldValidatorParam.add(mntmDelete);										
	}
	

	private void initMenu4TableConstraints(){
		_menu4TableConstraints = new JPopupMenu();
		
		JMenuItem mntmNew = new JMenuItem("New Table Constraint");
		mntmNew.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				DefaultMutableTreeNode tableConstraintsNode =  (DefaultMutableTreeNode)_tree.getLastSelectedPathComponent();
				TableConstraint constraint = new TableConstraint();
				constraint.setName("primary key");
				DefaultMutableTreeNode tableConstraintNode = new DefaultMutableTreeNode(constraint);
				//tableNode.setUserObject(table);
				tableConstraintsNode.add(tableConstraintNode);
				TreeNode[] nodes = tableConstraintNode.getPath();  
                TreePath path = new TreePath(nodes);  
                _tree.scrollPathToVisible(path);  
				_tree.updateUI();
			}
		});
		_menu4TableConstraints.add(mntmNew);										
	}
	

	private void initMenu4TableConstraint(){
		_menu4TableConstraint = new JPopupMenu();
		
		JMenuItem mntmDelete = new JMenuItem("Delete Table Constraint");
		mntmDelete.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				removeCurrentNode();
				logger.debug("Delete Table Constraint - clicked!");
			}
		});
		_menu4TableConstraint.add(mntmDelete);										
	}

	private void initMenu4APIS(){
		_menu4APIS = new JPopupMenu();
		
		JMenuItem mntmNew = new JMenuItem("New API");
		mntmNew.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				DefaultMutableTreeNode apisNode =  (DefaultMutableTreeNode)_tree.getLastSelectedPathComponent();
				API api = new API();
				api.setName(api.getName());
				DefaultMutableTreeNode apiNode = new DefaultMutableTreeNode(api);
				//tableNode.setUserObject(table);
				apisNode.add(apiNode);
				TreeNode[] nodes = apiNode.getPath();  
                TreePath path = new TreePath(nodes);  
                _tree.scrollPathToVisible(path);  
				_tree.updateUI();
				MetaDataTreeHelper.insertAPI(apiNode, api);
			}
		});
		_menu4APIS.add(mntmNew);										
	}

	private void initMenu4API(){
		_menu4API = new JPopupMenu();
		
		JMenuItem mntmDelete = new JMenuItem("Delete API");
		mntmDelete.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				removeCurrentNode();
				logger.debug("Delete API - clicked!");
			}
		});
		_menu4API.add(mntmDelete);										
	}
	
	private void initMenu4APIParams(){
		_menu4APIParams = new JPopupMenu();
		
		JMenuItem mntmNew = new JMenuItem("New API Param");
		mntmNew.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				DefaultMutableTreeNode apisParamsNode =  (DefaultMutableTreeNode)_tree.getLastSelectedPathComponent();
				APIParam apiParam = new APIParam();
				apiParam.setName(apiParam.getName());
				DefaultMutableTreeNode apiParamNode = new DefaultMutableTreeNode(apiParam);
				//tableNode.setUserObject(table);
				apisParamsNode.add(apiParamNode);
				TreeNode[] nodes = apiParamNode.getPath();  
                TreePath path = new TreePath(nodes);  
                _tree.scrollPathToVisible(path);  
				_tree.updateUI();
				MetaDataTreeHelper.insertAPIParam(apiParamNode, apiParam);
			}
		});
		_menu4APIParams.add(mntmNew);										
	}
	
	private void initMenu4APIParam(){
		_menu4APIParam = new JPopupMenu();
		
		JMenuItem mntmDelete = new JMenuItem("Delete API Param");
		mntmDelete.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				removeCurrentNode();
				logger.debug("Delete API Param - clicked!");
			}
		});
		_menu4APIParam.add(mntmDelete);										
	}
	

	private void initMenu4APIValidators(){
		_menu4APIValidators = new JPopupMenu();
		
		JMenuItem mntmNew = new JMenuItem("New API Validators");
		mntmNew.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				DefaultMutableTreeNode apiValidatorsNode =  (DefaultMutableTreeNode)_tree.getLastSelectedPathComponent();
				APIValidator apiValidator = new APIValidator();
				apiValidator.setType(apiValidator.getType());
				DefaultMutableTreeNode apiValidatorNode = new DefaultMutableTreeNode(apiValidator);
				//tableNode.setUserObject(table);
				apiValidatorsNode.add(apiValidatorNode);
				TreeNode[] nodes = apiValidatorNode.getPath();  
                TreePath path = new TreePath(nodes);  
                _tree.scrollPathToVisible(path);  
				_tree.updateUI();
				MetaDataTreeHelper.insertAPIValidator(apiValidatorNode, apiValidator);
			}
		});
		_menu4APIValidators.add(mntmNew);										
	}
	
	private void initMenu4APIValidator(){
		_menu4APIValidator = new JPopupMenu();
		
		JMenuItem mntmDelete = new JMenuItem("Delete API Validator");
		mntmDelete.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				removeCurrentNode();
				logger.debug("Delete API Validator - clicked!");
			}
		});
		_menu4APIValidator.add(mntmDelete);										
	}
	
	private void initMenu4APIValidatorParams(){
		_menu4APIValidatorParams = new JPopupMenu();
		
		JMenuItem mntmNew = new JMenuItem("New API Validator Params");
		mntmNew.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				DefaultMutableTreeNode apiValidatorParamsNode =  (DefaultMutableTreeNode)_tree.getLastSelectedPathComponent();
				APIValidatorParam apiValidatorParam = new APIValidatorParam();
				apiValidatorParam.setName(apiValidatorParam.getName());
				DefaultMutableTreeNode apiValidatorParamNode = new DefaultMutableTreeNode(apiValidatorParam);
				//tableNode.setUserObject(table);
				apiValidatorParamsNode.add(apiValidatorParamNode);
				TreeNode[] nodes = apiValidatorParamNode.getPath();  
                TreePath path = new TreePath(nodes);  
                _tree.scrollPathToVisible(path);  
				_tree.updateUI();
				MetaDataTreeHelper.insertAPIValidatorParam(apiValidatorParamNode, apiValidatorParam);
			}
		});
		_menu4APIValidatorParams.add(mntmNew);										
	}

	private void initMenu4APIValidatorParam(){
		_menu4APIValidatorParam = new JPopupMenu();
		
		JMenuItem mntmDelete = new JMenuItem("Delete API Validator Param");
		mntmDelete.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				removeCurrentNode();
				logger.debug("Delete API Validator Param - clicked!");
			}
		});
		_menu4APIValidatorParam.add(mntmDelete);										
	}
	
	public void showMessage(String message){
		String prevMessage = this._textAreaConsole.getText();
		_textAreaConsole.setText(prevMessage + "\n" + message);
	}
	public void clearMessages(){
		_textAreaConsole.setText("");
	}
	
	public static Main getInstance(){
		return _main;
	}
}
